Category Archives: Arduino

Free Online Tools or Software for Electronic Circuit Simulation

https://www.circuitlab.com/
Though free but only a few tries for each session. Not much useful.

https://www.multisim.com/
This is good. So  far I have used for simulating small sections like filters, transistor amplifiers etc. The free version served the purpose.

https://www.falstad.com/mathphysics.html
Various Simulation tools are there. Yet to explore much.

Please note – The information provided here is on as is basis. I don’t guarantee their accuracy and proper functioning.

esp8266-esp-01-wifi-module-for-iot

ESP-01 Flashing Errors

After a few years I started working with an ESP-01 again. But after so many years I forgot the exact parameters of module I have and was using default settings. For hours I couldn’t flash anything to it. Everytime flashing failed with one error or other. The most occurring errors are :

  1. Invalid (unsupported) command 0x8 
  2. Invalid head of packet (0x00)
  3. Invalid head of packet (0x0f)

The above problems can be due to two reasons mainly

  1. Wrong settings
  2. The module needs to be RESET to get the flashing started. The timing of pressing reset and time of holding it down is important. The RESET needs to be done after the Arduino IDE starts the flashing (…. progress bar). And the RESET will have to be hold low for  1 – 2 seconds.
  3. Inadequate power supply

Though many suggested that these errors are due to incompatible signal levels between Arduino and ESP but in my case it was not. Previously also I had successfully flashed without logic level converters.

Proper parameters for ESP-01. Please note Flash mode will need to be set as per the chip. Newer ones need DOUT specifically. Whereas the old ones work with both QIO and DOUT. Burning with wrong mode will result in a successful upload but the code will not work. 

ESP-8266 and NTP = onboard timekeeping

We can sync the time of a ESP-8266 with a NTP server and then keep time count on the device. It will not need any other additional devices like a DS1307 clock. And once synced with the NTP server it can keep the time even if there is no internet  – very handy.

The time formatting and display functions are standard C++ functions.

#include <ESP8266WiFi.h>

#include "TinyDHT.h"

const char *ssid     = "xxxxx";
const char *password = "xxxxxx";


#define DHTPIN11 14          // What digital pin we're connected to
#define DHTTYPE11 DHT11     // DHT 11

DHT dht11(DHTPIN11, DHTTYPE11);

struct tm* tm;

float temperature, relHumidity;
String currentTime;

#define countof(a) (sizeof(a) / sizeof(a[0]))

#define LED 13

void setup() {

  time_t now = 0;

  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500); 

  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");

  Serial.println("WiFi connected");
  
//sync time with the NTP server. First param 19800 seconds = +5:30 for IST, Second Param 0 = DST 
 configTime(19800, 0, "pool.ntp.org");

//waiting for time to get synced before proceeding. This is not strictly required. Please see after code 
  do
  {
    now = time(nullptr);
    delay(500);
    Serial.print("*");
  }while(now < time(nullptr));
  
  pinMode(LED, OUTPUT);
  
  pinMode(DHTPIN11, INPUT);
  dht11.begin();

  onLedIndicatorChange();
}


void loop() {
  // Your code here 
  time_t now = time(nullptr);
  
  char datestring[30];
  
  strftime(datestring, 
            countof(datestring),
            "%d/%m/%Y %I:%M:%S %p",
            localtime(&now)
            );
   
  currentTime = datestring; 
  Serial.println(currentTime);
  temperature = dht11.readTemperature();
  delay(200);
  relHumidity = dht11.readHumidity();
  delay(200);

}

void onLedIndicatorChange() {
  // Do something
  int ledIndicator = 1; 
  digitalWrite(LED, ledIndicator);
}

configtime listens for connection in the back and will sync as soon as a connection is available. So if a time is not critical for the successive codes or functions then the loop that waits for the sync can be skipped.

configTime(19800, 0, "pool.ntp.org");
do //loop and wait for a sync
{
  now = time(nullptr);
  delay(500);
  Serial.print("*");
}while(now < time(nullptr));

 

Sync Ds1302 with NTP

This code first syncs the DS1302 chip with a NTP server and then reads time from the DS1302 chip. Every time the system is booted the clock is synced with a NTP server.

#include <ESP8266WiFi.h>

#include "TinyDHT.h" // Adafruit library https://github.com/adafruit/TinyDHT

#include <ThreeWire.h> // needed by rtc
#include <RtcDS1302.h> // Makuna library https://github.com/Makuna/Rtc

const char *ssid     = "xxxxxxxxxxxx";
const char *password = "xxxx";


#define DHTPIN11 14          // Pin to which DHT11 connected to
#define DHTTYPE11 DHT11     // DHT 11

DHT dht11(DHTPIN11, DHTTYPE11);

ThreeWire myWire(5,16,4); // IO, SCLK, CE/Reset
RtcDS1302<ThreeWire> Rtc(myWire);
RtcDateTime currentTimeEpoch;

#define countof(a) (sizeof(a) / sizeof(a[0]))

float temperature, relHumidity;
String currentTime;

void initialiseRTC()
{
    //now = time(nullptr);
    //Serial.print(now);
    
    /*if (!Rtc.IsDateTimeValid()) 
    {
        // Common Causes:
        //    1) first time you ran and the device wasn't running yet
        //    2) the battery on the device is low or even missing

        Serial.println("RTC lost confidence in the DateTime!");
        //by default the RTC library assumes time from year 2000, but EPOCH starts from 1970. Severs returns EPOCH and that is the standard. So below converting the EPOCH to equivalent RTC date.   
        currentTimeEpoch.InitWithEpoch32Time(time(nullptr));
        Rtc.SetDateTime(currentTimeEpoch);
    }*/

    if (!Rtc.GetIsRunning())
    {
        Serial.println("RTC was not actively running, starting now");
        Rtc.SetIsRunning(true);
    }

    if (Rtc.GetIsWriteProtected())
    {
        Serial.println("RTC was write protected, enabling writing");
        Rtc.SetIsWriteProtected(false);
    }

    //here we are always syncing the clock when the device is booted. 
    currentTimeEpoch.InitWithEpoch32Time(time(nullptr));
    Rtc.SetDateTime(currentTimeEpoch);
    
    if (!Rtc.GetIsWriteProtected())
    {
        Serial.println("RTC was not write protected, disabling writing");
        Rtc.SetIsWriteProtected(true);
    }

}

#define LED 13

void setup() {
  time_t now = 0;
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500); 

  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");

  Serial.println("WiFi connected");
  
// here we are setting up the NTP call. Consequently we can just call time() to get the time. 
//the first parameter is Timezone in seconds, second parameter is DST in seconds and third parameter is the NTP server. 
  configTime(19800, 0, "pool.ntp.org"); 

//wait till the clock is synced, else wrong time will get set in the DS1302 chip 
  do   
  {
    // time(nullptr) - returns the time that was received from NTP server
    now = time(nullptr);
    delay(500);
    Serial.print("*");
  }while(now < time(nullptr));

  Rtc.Begin(); //initialise the RTC library
  initialiseRTC(); // this will set the NTP time in DS1302 clock chip,
  
  pinMode(LED, OUTPUT);
  
  pinMode(DHTPIN11, INPUT);
  dht11.begin();

  onLedIndicatorChange();
}

void loop() {
  // Your code here 
  RtcDateTime now = Rtc.GetDateTime(); // reading the time from DS1302 clock module
  char datestring[20];
  
  snprintf_P(datestring, 
            countof(datestring),
            PSTR("%02u/%02u/%04u %02u:%02u:%02u"),
            now.Month(),
            now.Day(),
            now.Year(),
            now.Hour(),
            now.Minute(),
            now.Second() );
   
  currentTime = datestring; 
  Serial.println(currentTime);
  temperature = dht11.readTemperature();
  delay(200);
  relHumidity = dht11.readHumidity();
  delay(200);

}

void onLedIndicatorChange() {
  // Do something
  int ledIndicator = 1; 
  digitalWrite(LED, ledIndicator);
}

3.3v Low Dropout Regulator (LDO) – MCP1826 / MCP1826

MCP1826 or MCP1826S is a very simple and easy to use LDO or Low Dropout Regulator from Microchip Technology. There are both fixed voltage and variable voltage versions available. The company also makes custom chips. It’s features are:
  • 1000 mA Output Current Capability
  • Input Operating Voltage Range: 2.3V to 6.0V
  • Adjustable Output Voltage Range: 0.8V to 5.0V (MCP1826 only)
  • Standard Fixed Output Voltages:
    • 0.8V, 1.2V, 1.8V, 2.5V, 3.0V, 3.3V, 5.0V
  • Low Dropout Voltage: 250 mV Typical at 1000 mA
  • Typical Output Voltage Tolerance: 0.5%
  • Stable with 1.0 μF Ceramic Output Capacitor
  • Fast Response to Load Transients
  • Low Supply Current: 120 μA (typ)
  • Low Shutdown Supply Current: 0.1 μA (typ) (MCP1826 only)
  • Fixed Delay on Power Good Output (MCP1826 only)
  • Short Circuit Current Limiting and Overtemperature Protection
  • TO-263-5 (DDPAK-5), TO-220-5, SOT-223-5 Package Options (MCP1826).
  • TO-263-3 (DDPAK-3), TO-220-3, SOT-223-3 Package Options (MCP1826S).
MCP1826 has  a POWERGOOD / ADJUST (depending on version) and SHUTDOWN. The MCP-1826S version is more simple and has only IN, OUT, GND                                                                      MCP-1826S                                                                    MCP-1826 Here are the Eagle files for  MCP-1826S   and    MCP-1826 Here is the Datasheet

How to Setup MQTT Server on a Windows 10 Desktop

  1. Download the Win32 installer from the below link (I couldn’t successfully installed the CygWin version)
    https://mosquitto.org/download/
  2. Once downloaded, install the package
  3. During the start of the installation process it will show links from where some dependencies will have to be downloaded
  4. Copy/Open the links
  5. Once the installation finishes go to the websites opened in the previous step
  6. Download the OpenSSL installer and the pthreadVC2.dll file
  7. Install the OpenSSL
  8. Copy the pthreadVC2.dll file to the directory where mosquitto executable has been installed. Normally C:\Program Files (x86)\mosquitto
  9. Open folder where OpenSSL got installed (normally C:\OpenSSL\) and open the lib folder (normally C:\OpenSSL\lib)
  10. Copy ssleay32.lib and libeay32.lib into the folder where mosquitto executable has been installed.
  11. Please note – while copying the files Windows might ask for giving Admin permission. Go ahead.
  12. At this point Mosquitto should be ready to run————————————————————–
  13. Now testing mosquitto
  14. Open a Command Prompt
  15. Goto the folder where mosquitto is installed
  16. Give command mosquitto.exe -v -c mosquitto.conf
  17. The server should now start listening on port 1883
  18. Now open another Command Prompt
  19. Give the command mosquitto_sub -h localhost -t channel1/data1
  20. Open a third Command Prompt and give the command mosquitto_pub -h localhost -t channel1/data1 -m “test data”
  21. In the command prompt where we used mosquitto_sub (step 18 and 19) will show the message “test data” sent from the third command prompt.
  22. Reaching this point means mosquitto is working fine———————————————-
  23. To secure the transmission we can username and password authentication
  24. Open a command prompt with Admin privileges
  25. Goto the folder where Mosquitto is installed
  26. Create a password file (for the first time only) using the command mosquitto_passwd.exe -c passfile.txt username
  27. It will ask for password. Give the password and confirm the password
  28. After this point further users can be added using the below command mosquitto_passwd.exe -b passfile.txt username password
    Please note – this time we supplied the password also along with the username
  29. Now edit the config file (mosquitto.conf normally located in C:\Program Files (x86)\mosquitto) to enforce only authenticated data transfers
  30. Uncomment allow_anonymous and set it false
  31. Uncomment password_file and put the password file name after it. It will look like password_file passfile.txt
  32. Now onwards all sub and pub requests will have to be with username and password of a user whose details exists in the password file. Examples below
    mosquitto_pub -h localhost -t channel1/data1 -m "test data" -u john -P johnpass 
    
    mosquitto_sub -h localhost -t channel1/data1 -u jane -P janepass
  33. Access control can be done using a acl file or using mosquitto-auth-plug (https://github.com/jpmens/mosquitto-auth-plug)
  34. There should be a aclfile.example inside your mqtt directory. If not then also no problem we will shortly see the contents of the file below.
  35. Create a file with any name. Here we will use aclFile.txt
  36. In the mosquitto.conf file uncomment acl_file and put the name of your acl file after that. It will look something like acl_file aclFile.txt
  37. Example content of aclFile.txt as below
     # user jane given full permission to channel1/data1 and only read permission to channel1/data2
    user jane
    topic channel1/data1
    topic read channel1/data2
    
    # user jane given full permission to both data1 and data2 channel
    user john
    topic channel1/#

Please put in your suggestions in comment.

MQTT on Windows  — Download link of Word File containing the above steps. WordPress had made some filenames missing. So uploaded the original word doc. 

Arduino as an Oscilloscope

Yes an Arduino can be used as Oscilloscope without any additional hardware.

Burn this code to Arduino

const int probePin = A0;
 
void setup() {
  //Setup serial connection
  Serial.begin(9600); 
}
 
void loop() {
  //Read analog pin
  int val = analogRead(probePin);
 
  //Write analog value to serial port:
  Serial.write( 0xff ); //can be skipped                                                    
  Serial.write( (val >> 8) & 0xff ); //the higher 8 bits                                            
  Serial.write( val & 0xff ); //the lower 8 bits
}

Download Processing from https://processing.org/download/  This tool will be used to run a C code that will plot the graphs.

Now run this C code in Processing

/*
 * Oscilloscope
 * Gives a visual rendering of analog pin 0 in realtime.
 * 
 * This project is part of Accrochages
 * See http://accrochages.drone.ws
 * 
 * (c) 2008 Sofian Audry ([email protected])
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */ 
import processing.serial.*;

Serial port;  // Create object from Serial class
int val;      // Data received from the serial port
int[] values;
float zoom;

void setup() 
{
  size(1280, 480);
  // Open the port that the board is connected to and use the same speed (9600 bps)
  port = new Serial(this, Serial.list()[0], 9600);
  values = new int[width];
  zoom = 1.0f;
  smooth();
}

int getY(int val) {
  return (int)(height - val / 1023.0f * (height - 1));
}

int getValue() {
  int value = -1;
  while (port.available() >= 3) {
    if (port.read() == 0xff) {
      value = (port.read() << 8) | (port.read());
    }
  }
  return value;
}

void pushValue(int value) {
  for (int i=0; i<width-1; i++)
    values[i] = values[i+1];
  values[width-1] = value;
}

void drawLines() {
  stroke(255);
  
  int displayWidth = (int) (width / zoom);
  
  int k = values.length - displayWidth;
  
  int x0 = 0;
  int y0 = getY(values[k]);
  for (int i=1; i<displayWidth; i++) {
    k++;
    int x1 = (int) (i * (width-1) / (displayWidth-1));
    int y1 = getY(values[k]);
    line(x0, y0, x1, y1);
    x0 = x1;
    y0 = y1;
  }
}

void drawGrid() {
  stroke(255, 0, 0);
  line(0, height/2, width, height/2);
}

void keyReleased() {
  switch (key) {
    case '+':
      zoom *= 2.0f;
      println(zoom);
      if ( (int) (width / zoom) <= 1 )
        zoom /= 2.0f;
      break;
    case '-':
      zoom /= 2.0f;
      if (zoom < 1.0f)
        zoom *= 2.0f;
      break;
  }
}

void draw()
{
  background(0);
  drawGrid();
  val = getValue();
  if (val != -1) {
    pushValue(val);
  }
  drawLines();
}

This is not replacement for an actual oscilloscope. It is a simple one that can used to monitor signal levels and voltages.

Burning Arduino Bootloader to Atmega8 or other Atmega

This is for all who are having problems in burning the Arduino Bootloader on an Atmega8 or any other Atmega Processor using a Arduino Board like Arduino Uno.

  1. The processor for the first time burning will have to be used with an external oscillator. I was trying without the external oscillator (was depending on the internal oscillator -  setup the fuses also properly) and was banging my head. 
  2. The Arduino Uno (or any other board that you are using) will have to be burned with the ArduinoISP code. (Files -> Examples -> ArduinoISP -> ArduinoISP)
  3. Don't bother about the Chip Configurations (and/or binary) that are available on the net, especially if you are looking to use the external oscillator. None works properly.Find a board from the existing list that uses the same Processor. 
  4. For Atmega8 use the "Arduino NG or older" from the boards list. That board should also work for Atmega168
  5. If you are using a 8MHZ crystal then open the "boards.txt" files under "Program Files (x86)\Arduino\hardware\arduino\avr".  And edit the "atmegang.build.f_cpu". Change it to "8000000L".
  6. If you will be using the Internal Oscillator then you will have to change the fuse values to proper ones in the above board configuration.
  7. I had problems with high bitrate while burning. So I changed it to "9600" (atmegang.upload.speed=9600).
  8. After you are done with the configurations and connections use the option "Burn Bootloader" under Tools in the Arduino IDE

 

I also found tutorials where it was suggested to remove the processor from board (UNO board) which is being used as programmer. Don’t do that.

Putting the chip in an UNO board didn’t work for me. I don’t know why but it didn’t.

What I found is the Atmega8 works best with the external oscillator. With an internal oscillator I was having problems after running the chip continuously for quite some time.

 

The connections with an Arduino UNO
------------------                --------------------------
Arduino Uno                         Atmega 8 or other
------------------                --------------------------
10                                      Reset  (1 on Atmega8)
11                                      MOSI   (17 on Atmega8)
12                                      MISO   (18 on Atmega8)
13                                      SCLK   (19 on Atmega8)
And the AVCC pin should be externally connected to VCC, even if the ADC is not used.

 

And like many suggested on the Internet already, a standalone programmer is the best. I got a USBasp from eBay.

And I guess it is better to invest in a 328p processor due to limited resource of Atmega8 chip. More or less same price.

Atmega8 IC can be used as standalone IC, that is without using the whole Arduino board. Please see this article for details : Using Atmega8 or Atmega328p directly without using Arduino boards and Atmega8 to Arduino pin mapping