Pages

Monday, 9 April 2018

Arduino OTA - through ESP8266 and SD Card

                                            
1. Overview :
The goal of this project is to provide over-the-air (OTA) upload of Arduino sketches to a remote Arduino. This is accomplished by programming the remote Arduino using ESP826612E and SD Card. ESP826612E code searches the SD card for a single file (“filename.hex”). This file is sent over to the target Arduino and new firmware is installed.

2. Requirements

 2.1. Hardware: 
▪ Arduino Uno 
▪ ESP826612E
▪ SD Card Breakout board. 
▪ Micro SD Card. 
▪ Mini a to b USB cable 
▪ Jumpers. 
▪ Patch Cords 

2.2. Software:
 ▪ Arduino IDE.
 ▪ ESP8266 Flasher Application for flashing NodeMCU1.0 firmware. 
 ▪ NodeMCU1.0 firmware .bin file.
 ▪ Boot Drive source code. 

3. Procedure Summary
 ▪ Install ESP826612E Add-On to arduino IDE.
 ▪ Load NodeMCU1.0 firmware for ESP826612E. 
 ▪ Set up hardware.
 ▪ Upload Boot Drive Code. 
 ▪ See the Result in Arduino.

4. Install ESP826612E Add-on to arduino IDE 
Step 1: Open Arduino IDE.


Step 2: Go to File > Preferences as shown below:

Step 3: Clicking the Preferences, you will find a window as shown below:

Step 4: Now you need to open the Window Icon as shown below:

Step 5: Opening this Window Icon, you will find Additional Boards Manager URL’s: Here you need to add up the following link:
http://arduino.esp8266.com/stable/package_esp8266com_index.json

Once you enter the additional URL, you need to hit OK.
Step 6: Then Navigate Board Manager by following Tools > Board > Board Manager which is as shown below:

Step 7: You will find a Window as shown below:

Step 8: Click on Type in the top of the window and select Contributed as shown below:

Step 9: Selecting the Contributed, you will find esp8266 by ESP8266 Community as shown below. Then Select the Online Help, as shown below:

Step 10: Once you select online help, you will be asked to select the version. There you will have to select version 2.0.0 and hit Install as shown below

Step 11: Once you hit Install, it will download and Install it., you will find as shown below:
Once it

Once it is installed you will find INSTALLED in blue and then close the window.
Step 12: Choose the board. Tools > Board > NodeMCU 1.0 (ESP-12E Module).

5. Install ESP826612E Add-on to arduino IDE
Step 1: Open ESP8266 Flash Application.

Step 2: Select the correct COM port.
Refer Computer->System properties-> Device Manager->Ports

Step 3: Browse the correct bin file.

Step 4: Before hitting download button, Long press the Reset switch of WiFi Module (No.1) first for 1-2 seconds and then long press the Reset switch of the board (No 2) for 1-2 seconds to which you WiFi Module is placed on as shown below. Keep them long pressed for 1-2 second together and then and then release switch 2 first and then release switch 1.

Step 5: Click Download. While esp8266 firmware is updating the blue LED on esp8266 module blinks rapidly.



7. Hardware Connection


Pin connections in the diagram is slightly different and hence do refer below for pin numbers.
ESP826612E to Arduino Uno Connections:
ESP826612E GPIO2 (pin 17) 
-------->      Arduino RST
GND                           
-------->      GND
ESP826612E TX       
-------->      Arduino RX
ESP826612E RX      
-------->      Arduino TX

SD Card Interface to ESP826612E:
ESP826612E GPIO13 (pin 7)     
-------->      SD breakout MOSI
ESP826612E GPIO12 (pin 6)     
-------->      SD breakout MISO
ESP826612E GPIO14 (pin 5)     
-------->      SD breakout CLK
ESP826612E GPIO16 (pin 4)
-------->      SD breakout CS
ESP826612E GND                       
-------->      SD breakout GND
ESP826612E 5V                          
-------->      SD breakout 5V


Optional debugging serial interface (This lets you see error messages and the like).
ESP826612E GND    
-------->      FTDI cable GND
ESP826612E GPIO5 (Pin 20)
-------->      FTDI cable RX


After hardware connections are done, continue from section 6.

1.     OTA of remote Arduino using Another Arduino.

1.1.  Hardware Set Up for OTA Programming of remote Arduino from Another Arduino

Pin connections in the diagram is slightly different and hence do refer below for pin numbers.
Master Arduino Uno to Target Arduino Uno Connections:
Master Arduino Digital Pin 6 
-------->      Target Arduino RST
Master Arduino GND                           
-------->      Target Arduino GND
Master Arduino Digital Pin 1 (TX)      
-------->      Target Digital Pin 0 (TX)      
Master Arduino Digital Pin 0 (RX)      
-------->      Target Digital Pin 1 (TX)      
SD Card Interface to Master Arduino Uno:
Master Arduino Digital Pin 11
-------->      SD breakout MOSI
Master Arduino Digital Pin 12
-------->      SD breakout MISO
Master Arduino Digital Pin 13
-------->      SD breakout CLK
Master Arduino Digital Pin 10
-------->      SD breakout CS
Master Arduino GND
-------->      SD breakout GND
Master Arduino 5V
-------->      SD breakout 5V


Optional debugging serial interface (This lets you see error messages and the like).
Master Arduino GND    
-------->      FTDI cable GND
Master Arduino Digital Pin 5
-------->      FTDI cable RX


After hardware connections are done, continue from section 6.

1.     Considerations while choosing ESP8266/Master Arduino for programming

§  When ESP826612E is used for OTA process, espsoftwareserial library needs to be used.
§  When Master Arduino is used for OTA process, the in-built SoftwareSerial library needs to be used.
§  BootDrive source code remains same for both the procedure (OTA programming of remote arduino using esp8266 and OTA programming using another arduino).

2.     BootDrive Source Code

2.1.          BootDrive.ino

#include <SoftwareSerial.h>
#include "stk500.h"
#include <SD.h>
/* Read hex file from sd/micro-sd card and program
 *  another arduino via ttl serial.
 * borrows heavily from avrdude source code (GPL license)
 *   Copyright (C) 2002-2004 Brian S. Dean <bsd@bsdhome.com>
 *   Copyright (C) 2008 Joerg Wunsch
 *  Created 12/26/2011 Kevin Osborn
 */

#define BOOT_BAUD 115200
#define DEBUG_BAUD 19200
/* different pins will be needed for I2SD, as 2/3 are leds */
#define txPin 5
#define rxPin 0
#define rstPin 2

/* uncomment this line if using arduino for OTA programming remote arduino */
//SoftwareSerial sSerial= SoftwareSerial(rxPin,txPin);

/* comment this line if using arduino for OTA programming remote arduino */
SoftwareSerial sSerial= SoftwareSerial(rxPin,txPin,128);

/* set up variables using the SD utility library functions */
SdFile root;
File myFile;
avrmem mybuf;
unsigned char mempage[128];

/* chipselect for the wyolum i2sd is 10 */

/* uncomment this line if using arduino for OTA programming remote arduino */

//const int chipSelect = 10;
/* comment this line if using arduino for OTA programming remote arduino */

const int chipSelect = 4;  

/* STANDALONE_DEBUG sends error messages out the main serial port.
   Not useful after you are actually trying to slave another arduino
*/
#ifdef STANDALONE_DEBUG
#define DEBUGPLN Serial.println
#define DEBUGP Serial.print
#else
#define DEBUGPLN sSerial.println
#define DEBUGP sSerial.print
#endif

void setup() {
 /* initialize serial port. Note that it's a good idea to use the softserial     
    library here, so you can do debugging on USB.
  */
  mybuf.buf = &mempage[0];
  sSerial.begin(DEBUG_BAUD);
  // and the regular serial port for error messages, etc.
  Serial.begin(BOOT_BAUD);
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  pinMode(rstPin,OUTPUT);
  pinMode(chipSelect,OUTPUT);
  
/* see if the card is present and can be initialized:*/
  if (!SD.begin(chipSelect)) {
    DEBUGPLN("Card failed, or not present");
    // don't do anything more:
    return;
  }
  DEBUGPLN("card initialized.");
  blinky(2,200);
  delay(5000);
  programArduino("Fade.hex");

}

void loop() {
  /* put your main code here, to run repeatedly: */
  
}

/* Line Buffer is set up in global SRAM */
#define LINELENGTH 50
unsigned char linebuffer[LINELENGTH];
unsigned char linemembuffer[16];
int readPage(File input, avrmem *buf)
{
  int len;
  int address;
  int total_len =0;
  // grab 128 bytes or less (one page)
  for (int i=0 ; i < 8; i++){
    len = readIntelHexLine(input, &address, &linemembuffer[0]);
    if (len < 0)
      break;
    else
      total_len=total_len+len;
    if (i==0)// first record determines the page address
      buf->pageaddress = address;
    memcpy((buf->buf)+(i*16), linemembuffer, len);
  }
  buf->size = total_len;
  return total_len;
  
}
// read one line of intel hex from file. Return the number of databytes
// Since the arduino code is always sequential, ignore the address for now.
// If you want to burn bootloaders, etc. we'll have to modify to
// return the address.

// INTEL HEX FORMAT:
// :<8-bit record size><16bit address><8bit record type><data...><8bit checksum>
int readIntelHexLine(File input, int *address, unsigned char *buf){
  unsigned char c;
  int i=0;
  while (true){
    if (input.available()){
      c = input.read();
      // this should handle unix or ms-dos line endings.
      // break out when you reach either, then check
      // for lf in stream to discard
      if ((c == 0x0d)|| (c == 0x0a))
        break;
      else
        linebuffer[i++] =c;
    }
    else return -1; //end of file
  }
  linebuffer[i]= 0; // terminate the string
  //peek at the next byte and discard if line ending char.
  if (input.peek() == 0xa)
    input.read();
  int len = hex2byte(&linebuffer[1]);
  *address = (hex2byte(&linebuffer[3]) <<8) |
               (hex2byte(&linebuffer[5]));
  int j=0;
  for (int i = 9; i < ((len*2)+9); i +=2){
    buf[j] = hex2byte(&linebuffer[i]);
    j++;
  }
  return len;
}
unsigned char hex2byte(unsigned char *code){
  unsigned char result =0;

  if ((code[0] >= '0') && (code[0] <='9')){
    result = ((int)code[0] - '0') << 4;
  }
  else if ((code[0] >='A') && (code[0] <= 'F')) {
    result = ((int)code[0] - 'A'+10) << 4;
  }
  if ((code[1] >= '0') && (code[1] <='9')){
    result |= ((int)code[1] - '0');
  }
  else if ((code[1] >='A') && (code[1] <= 'F'))  
    result |= ((int)code[1] -'A'+10);  
return result;
}

// Right now there is only one file.
void programArduino(char * filename){

  digitalWrite(rstPin,HIGH);

  unsigned int major=0;
  unsigned int minor=0;
  delay(100);
   toggle_Reset();
   delay(10);
   stk500_getsync();
   stk500_getparm(Parm_STK_SW_MAJOR, &major);
  DEBUGP("software major: ");
  DEBUGPLN(major);
  stk500_getparm(Parm_STK_SW_MINOR, &minor);
  DEBUGP("software Minor: ");
  DEBUGPLN(minor);
if (SD.exists(filename)){
    myFile = SD.open(filename, FILE_READ);
  }
  else{
    DEBUGP(filename);
    DEBUGPLN(" doesn't exist");
    return;
  }
  //enter program mode
  stk500_program_enable();


  while (readPage(myFile,&mybuf) > 0){
    stk500_loadaddr(mybuf.pageaddress>>1);
    stk500_paged_write(&mybuf, mybuf.size, mybuf.size);
  }

  // could verify programming by reading back pages and comparing but for now, close out
  stk500_disable();
  delay(10);
  toggle_Reset();
  myFile.close();
  blinky(4,500);
  
  
}
void blinky(int times, long delaytime){
  for (int i = 0 ; i < times; i++){
//    digitalWrite(LED1,HIGH);
    delay(delaytime);
//    digitalWrite(LED1, LOW);
    delay (delaytime);
  }
  
}
void toggle_Reset()
{
  digitalWrite(rstPin, LOW);
  delayMicroseconds(1000);
  digitalWrite(rstPin,HIGH);
}
static int stk500_send(byte *buf, unsigned int len)
{

  Serial.write(buf,len);
 // sSerial.write(buf,len);
}
static int stk500_recv(byte * buf, unsigned int len)
{
  int rv;


  rv = Serial.readBytes((char *)buf,len);
  if (rv < 0) {
    error(ERRORNOPGMR);
    return -1;
  }
  return 0;
}
int stk500_drain()
{
  while (Serial.available()> 0)
  {  
    DEBUGP("draining: ");
    DEBUGPLN(Serial.read(),HEX);
  }
  return 1;
}
int stk500_getsync()
{
  byte buf[32], resp[32];

  /*
   * get in sync */
  buf[0] = Cmnd_STK_GET_SYNC;
  buf[1] = Sync_CRC_EOP;
  
  /*
   * First send and drain a few times to get rid of line noise
   */
  
  stk500_send(buf, 2);
  stk500_drain();
  stk500_send(buf, 2);
  stk500_drain();
  
  stk500_send(buf, 2);
  if (stk500_recv(resp, 1) < 0)
    return -1;
  if (resp[0] != Resp_STK_INSYNC) {
        error1(ERRORPROTOSYNC,resp[0]);
    stk500_drain();
    return -1;
  }

  if (stk500_recv(resp, 1) < 0)
    return -1;
  if (resp[0] != Resp_STK_OK) {
    error1(ERRORNOTOK,resp[0]);
    return -1;
  }
  return 0;
}
static int stk500_getparm(unsigned parm, unsigned * value)
{
  byte buf[16];
  unsigned v;
  int tries = 0;

 retry:
  tries++;
  buf[0] = Cmnd_STK_GET_PARAMETER;
  buf[1] = parm;
  buf[2] = Sync_CRC_EOP;

  stk500_send(buf, 3);

  if (stk500_recv(buf, 1) < 0)
  {
//    exit(1);
    cli(); //disable interrupts
    while(1); //forever loop
  }
  if (buf[0] == Resp_STK_NOSYNC) {
    if (tries > 33) {
      error(ERRORNOSYNC);
      return -1;
    }
   if (stk500_getsync() < 0)
      return -1;
      
    goto retry;
  }
  else if (buf[0] != Resp_STK_INSYNC) {
    error1(ERRORPROTOSYNC,buf[0]);
    return -2;
  }

  if (stk500_recv(buf, 1) < 0)
  {
//    exit(1);
    cli(); //disable interrupts
    while(1); //forever loop
  }
  v = buf[0];

  if (stk500_recv(buf, 1) < 0)
  {
//    exit(1);
    cli(); //disable interrupts
    while(1); //forever loop
  }
  if (buf[0] == Resp_STK_FAILED) {
    error1(ERRORPARMFAILED,v);
    return -3;
  }
  else if (buf[0] != Resp_STK_OK) {
    error1(ERRORNOTOK,buf[0]);
    return -3;
  }

  *value = v;

  return 0;
}
/* read signature bytes - arduino version */
static int arduino_read_sig_bytes(AVRMEM * m)
{
  unsigned char buf[32];

  /* Signature byte reads are always 3 bytes. */

  if (m->size < 3) {
    DEBUGPLN("memsize too small for sig byte read");
    return -1;
  }

  buf[0] = Cmnd_STK_READ_SIGN;
  buf[1] = Sync_CRC_EOP;

  stk500_send(buf, 2);

  if (stk500_recv(buf, 5) < 0)
    return -1;
  if (buf[0] == Resp_STK_NOSYNC) {
    error(ERRORNOSYNC);
     return -1;
  } else if (buf[0] != Resp_STK_INSYNC) {
    error1(ERRORPROTOSYNC,buf[0]);
     return -2;
  }
  if (buf[4] != Resp_STK_OK) {
    error1(ERRORNOTOK,buf[4]);
    return -3;
  }

  m->buf[0] = buf[1];
  m->buf[1] = buf[2];
  m->buf[2] = buf[3];

  return 3;
}

static int stk500_loadaddr(unsigned int addr)
{
  unsigned char buf[16];
  int tries;

  tries = 0;
 retry:
  tries++;
  buf[0] = Cmnd_STK_LOAD_ADDRESS;
  buf[1] = addr & 0xff;
  buf[2] = (addr >> 8) & 0xff;
  buf[3] = Sync_CRC_EOP;


  stk500_send(buf, 4);

  if (stk500_recv(buf, 1) < 0)
  {
//    exit(1);
    cli(); //disable interrupts
    while(1); //forever loop
  }
  if (buf[0] == Resp_STK_NOSYNC) {
    if (tries > 33) {
      error(ERRORNOSYNC);
      return -1;
    }
    if (stk500_getsync() < 0)
      return -1;
    goto retry;
  }
  else if (buf[0] != Resp_STK_INSYNC) {
    error1(ERRORPROTOSYNC, buf[0]);
    return -1;
  }

  if (stk500_recv(buf, 1) < 0)
  {
//    exit(1);
    cli(); //disable interrupts
    while(1); //forever loop
  }
  if (buf[0] == Resp_STK_OK) {
    return 0;
  }

  error1(ERRORPROTOSYNC, buf[0]);
  return -1;
}
static int stk500_paged_write(AVRMEM * m,
                              int page_size, int n_bytes)
{
  // This code from avrdude has the luxury of living on a PC and copying buffers around.
  // not for us...
 // unsigned char buf[page_size + 16];
 unsigned char cmd_buf[16]; //just the header
  int memtype;
 // unsigned int addr;
  int block_size;
  int tries;
  unsigned int n;
  unsigned int i;
  int flash;

  // Fix page size to 128 because that's what arduino expects
  page_size = 128;
  //EEPROM isn't supported
  memtype = 'F';
  flash = 1;


    /* build command block and send data separeately on arduino*/
    
    i = 0;
    cmd_buf[i++] = Cmnd_STK_PROG_PAGE;
    cmd_buf[i++] = (page_size >> 8) & 0xff;
    cmd_buf[i++] = page_size & 0xff;
    cmd_buf[i++] = memtype;
    stk500_send(cmd_buf,4);
    stk500_send(&m->buf[0], page_size);
    cmd_buf[0] = Sync_CRC_EOP;
    stk500_send( cmd_buf, 1);

    if (stk500_recv(cmd_buf, 1) < 0)
//      exit(1); // errr need to fix this...
    {
  //    exit(1);
      cli(); //disable interrupts
      while(1); //forever loop
    }
    if (cmd_buf[0] == Resp_STK_NOSYNC) {
        error(ERRORNOSYNC);
        return -3;
     }
    else if (cmd_buf[0] != Resp_STK_INSYNC) {

     error1(ERRORPROTOSYNC, cmd_buf[0]);
      return -4;
    }
    
    if (stk500_recv(cmd_buf, 1) < 0)
    {
  //    exit(1);
      cli(); //disable interrupts
      while(1); //forever loop
    }
    if (cmd_buf[0] != Resp_STK_OK) {
    error1(ERRORNOTOK,cmd_buf[0]);

      return -5;
    }
  

  return n_bytes;
}
#ifdef LOADVERIFY //maybe sometime? note code needs to be re-written won't work as is
static int stk500_paged_load(AVRMEM * m,
                             int page_size, int n_bytes)
{
  unsigned char buf[16];
  int memtype;
  unsigned int addr;
  int a_div;
  int tries;
  unsigned int n;
  int block_size;

  memtype = 'F';


  a_div = 1;

  if (n_bytes > m->size) {
    n_bytes = m->size;
    n = m->size;
  }
  else {
    if ((n_bytes % page_size) != 0) {
      n = n_bytes + page_size - (n_bytes % page_size);
    }
    else {
      n = n_bytes;
    }
  }

  for (addr = 0; addr < n; addr += page_size) {
//    report_progress (addr, n_bytes, NULL);

    if ((addr + page_size > n_bytes)) {
        block_size = n_bytes % page_size;
     }
     else {
        block_size = page_size;
     }
  
    tries = 0;
  retry:
    tries++;
    stk500_loadaddr(addr/a_div);
    buf[0] = Cmnd_STK_READ_PAGE;
    buf[1] = (block_size >> 8) & 0xff;
    buf[2] = block_size & 0xff;
    buf[3] = memtype;
    buf[4] = Sync_CRC_EOP;
    stk500_send(buf, 5);

    if (stk500_recv(buf, 1) < 0)
    {
  //    exit(1);
      cli(); //disable interrupts
      while(1); //forever loop
    }
    if (buf[0] == Resp_STK_NOSYNC) {
      if (tries > 33) {
        error(ERRORNOSYNC);
        return -3;
      }
      if (stk500_getsync() < 0)
     return -1;
      goto retry;
    }
    else if (buf[0] != Resp_STK_INSYNC) {
      error1(ERRORPROTOSYNC, buf[0]);
      return -4;
    }

    if (stk500_recv(&m->buf[addr], block_size) < 0)
    {
  //    exit(1);
      cli(); //disable interrupts
      while(1); //forever loop
    }

    if (stk500_recv(buf, 1) < 0)
    {
  //    exit(1);
      cli(); //disable interrupts
      while(1); //forever loop
    }

    if (buf[0] != Resp_STK_OK) {
        error1(ERRORPROTOSYNC, buf[0]);
        return -5;
      }
    }
  

  return n_bytes;
}
#endif

/*
 * issue the 'program enable' command to the AVR device
 */
static int stk500_program_enable()
{
  unsigned char buf[16];
  int tries=0;

 retry:
  
  tries++;

  buf[0] = Cmnd_STK_ENTER_PROGMODE;
  buf[1] = Sync_CRC_EOP;

  stk500_send( buf, 2);
  if (stk500_recv( buf, 1) < 0)
  {
//    exit(1);
    cli(); //disable interrupts
    while(1); //forever loop
  }
  if (buf[0] == Resp_STK_NOSYNC) {
    if (tries > 33) {
      error(ERRORNOSYNC);
      return -1;
    }
    if (stk500_getsync()< 0)
      return -1;
    goto retry;
  }
  else if (buf[0] != Resp_STK_INSYNC) {
    error1(ERRORPROTOSYNC,buf[0]);
    return -1;
  }

  if (stk500_recv( buf, 1) < 0)
  {
//    exit(1);
    cli(); //disable interrupts
    while(1); //forever loop
  }
  if (buf[0] == Resp_STK_OK) {
    return 0;
  }
  else if (buf[0] == Resp_STK_NODEVICE) {
    error(ERRORNODEVICE);
    return -1;
  }

  if(buf[0] == Resp_STK_FAILED)
  {
      error(ERRORNOPROGMODE);
       return -1;
  }


  error1(ERRORUNKNOWNRESP,buf[0]);

  return -1;
}

static void stk500_disable()
{
  unsigned char buf[16];
  int tries=0;

 retry:
  
  tries++;

  buf[0] = Cmnd_STK_LEAVE_PROGMODE;
  buf[1] = Sync_CRC_EOP;

  stk500_send( buf, 2);
  if (stk500_recv( buf, 1) < 0)
  {
//    exit(1);
    cli(); //disable interrupts
    while(1); //forever loop
  }
  if (buf[0] == Resp_STK_NOSYNC) {
    if (tries > 33) {
      error(ERRORNOSYNC);
      return;
    }
    if (stk500_getsync() < 0)
      return;
    goto retry;
  }
  else if (buf[0] != Resp_STK_INSYNC) {
    error1(ERRORPROTOSYNC,buf[0]);
    return;
  }

  if (stk500_recv( buf, 1) < 0)
  {
//    exit(1);
    cli(); //disable interrupts
    while(1); //forever loop
  }
  if (buf[0] == Resp_STK_OK) {
    return;
  }
  else if (buf[0] == Resp_STK_NODEVICE) {
    error(ERRORNODEVICE);
    return;
  }

  error1(ERRORUNKNOWNRESP,buf[0]);

  return;
}
//original avrdude error messages get copied to ram and overflow, wo use numeric codes.
void error1(int errno,unsigned char detail){
  DEBUGP("error: ");
  DEBUGP(errno);
  DEBUGP(" detail: 0x");
  DEBUGPLN(detail,HEX);
}


void error(int errno){
  DEBUGP("error" );
  DEBUGPLN(errno);
}
void dumphex(unsigned char *buf,int len)
{
  for (int i = 0; i < len; i++)
  {
    if (i%16 == 0)
      DEBUGPLN();
    DEBUGP(buf[i],HEX);DEBUGP(" ");
  }
  DEBUGPLN();
}
     



2.2.          Stk500.h

//**** ATMEL AVR - A P P L I C A T I O N   N O T E  ************************
//*
//* Title:           AVR061 - STK500 Communication Protocol
//* Filename:        command.h
//* Version:         1.0
//* Last updated:    09.09.2002
//*
//* Support E-mail:  avr@atmel.com
//*
//**************************************************************************

// *****************[ STK Message constants ]***************************

#define STK_SIGN_ON_MESSAGE "AVR STK"   // Sign on string for Cmnd_STK_GET_SIGN_ON
typedef struct avrmem {
  int size;
  unsigned int pageaddress;
  unsigned char *buf;
} AVRMEM;


// *****************[ STK Response constants ]***************************

#define Resp_STK_OK                0x10  // ' '
#define Resp_STK_FAILED            0x11  // ' '
#define Resp_STK_UNKNOWN           0x12  // ' '
#define Resp_STK_NODEVICE          0x13  // ' '
#define Resp_STK_INSYNC            0x14  // ' '
#define Resp_STK_NOSYNC            0x15  // ' '

#define Resp_ADC_CHANNEL_ERROR     0x16  // ' '
#define Resp_ADC_MEASURE_OK        0x17  // ' '
#define Resp_PWM_CHANNEL_ERROR     0x18  // ' '
#define Resp_PWM_ADJUST_OK         0x19  // ' '

// *****************[ STK Special constants ]***************************

#define Sync_CRC_EOP               0x20  // 'SPACE'

// *****************[ STK Command constants ]***************************

#define Cmnd_STK_GET_SYNC          0x30  // ' '
#define Cmnd_STK_GET_SIGN_ON       0x31  // ' '

#define Cmnd_STK_SET_PARAMETER     0x40  // ' '
#define Cmnd_STK_GET_PARAMETER     0x41  // ' '
#define Cmnd_STK_SET_DEVICE        0x42  // ' '
#define Cmnd_STK_SET_DEVICE_EXT    0x45  // ' '                   

#define Cmnd_STK_ENTER_PROGMODE    0x50  // ' '
#define Cmnd_STK_LEAVE_PROGMODE    0x51  // ' '
#define Cmnd_STK_CHIP_ERASE        0x52  // ' '
#define Cmnd_STK_CHECK_AUTOINC     0x53  // ' '
#define Cmnd_STK_LOAD_ADDRESS      0x55  // ' '
#define Cmnd_STK_UNIVERSAL         0x56  // ' '
#define Cmnd_STK_UNIVERSAL_MULTI   0x57  // ' '

#define Cmnd_STK_PROG_FLASH        0x60  // ' '
#define Cmnd_STK_PROG_DATA         0x61  // ' '
#define Cmnd_STK_PROG_FUSE         0x62  // ' '
#define Cmnd_STK_PROG_LOCK         0x63  // ' '
#define Cmnd_STK_PROG_PAGE         0x64  // ' '
#define Cmnd_STK_PROG_FUSE_EXT     0x65  // ' '            

#define Cmnd_STK_READ_FLASH        0x70  // ' '
#define Cmnd_STK_READ_DATA         0x71  // ' '
#define Cmnd_STK_READ_FUSE         0x72  // ' '
#define Cmnd_STK_READ_LOCK         0x73  // ' '
#define Cmnd_STK_READ_PAGE         0x74  // ' '
#define Cmnd_STK_READ_SIGN         0x75  // ' '
#define Cmnd_STK_READ_OSCCAL       0x76  // ' '
#define Cmnd_STK_READ_FUSE_EXT     0x77  // ' '            
#define Cmnd_STK_READ_OSCCAL_EXT   0x78  // ' '     

// *****************[ STK Parameter constants ]***************************

#define Parm_STK_HW_VER            0x80  // ' ' - R
#define Parm_STK_SW_MAJOR          0x81  // ' ' - R
#define Parm_STK_SW_MINOR          0x82  // ' ' - R
#define Parm_STK_LEDS              0x83  // ' ' - R/W
#define Parm_STK_VTARGET           0x84  // ' ' - R/W
#define Parm_STK_VADJUST           0x85  // ' ' - R/W
#define Parm_STK_OSC_PSCALE        0x86  // ' ' - R/W
#define Parm_STK_OSC_CMATCH        0x87  // ' ' - R/W
#define Parm_STK_RESET_DURATION    0x88  // ' ' - R/W
#define Parm_STK_SCK_DURATION      0x89  // ' ' - R/W

#define Parm_STK_BUFSIZEL          0x90  // ' ' - R/W, Range {0..255}
#define Parm_STK_BUFSIZEH          0x91  // ' ' - R/W, Range {0..255}
#define Parm_STK_DEVICE            0x92  // ' ' - R/W, Range {0..255}
#define Parm_STK_PROGMODE          0x93  // ' ' - 'P' or 'S'
#define Parm_STK_PARAMODE          0x94  // ' ' - TRUE or FALSE
#define Parm_STK_POLLING           0x95  // ' ' - TRUE or FALSE
#define Parm_STK_SELFTIMED         0x96  // ' ' - TRUE or FALSE
#define Param_STK500_TOPCARD_DETECT 0x98  // ' ' - Detect top-card attached

// *****************[ STK status bit definitions ]***************************

#define Stat_STK_INSYNC            0x01  // INSYNC status bit, '1' - INSYNC
#define Stat_STK_PROGMODE          0x02  // Programming mode,  '1' - PROGMODE
#define Stat_STK_STANDALONE        0x04  // Standalone mode,   '1' - SM mode
#define Stat_STK_RESET             0x08  // RESET button,      '1' - Pushed
#define Stat_STK_PROGRAM           0x10  // Program button, '   1' - Pushed
#define Stat_STK_LEDG              0x20  // Green LED status,  '1' - Lit
#define Stat_STK_LEDR              0x40  // Red LED status,    '1' - Lit
#define Stat_STK_LEDBLINK          0x80  // LED blink ON/OFF,  '1' - Blink

// **************************[Error messages]******************************//
#define ERRORUNKNOWNRESP 1 //stk500_disable(): unknown response=
#define ERRORNODEVICE 2
#define ERRORPROTOSYNC 3 //stk500_disable(): protocol error, expect=Resp_STK_INSYNC, resp=
#define ERRORNOSYNC 4  //can't get into sync
#define ERRORNOPROGMODE 5 //failed to get into programming mode
#define ERRORNOPGMR 6 //programmer not responding
#define ERRORNOTOK 7
#define ERRORPARMFAILED 8 // get parameter failed: response

// *****************************[ End Of COMMAND.H ]**************************

FOR ESP8266-CLICK HERE
FOR ARDUINO UNO - CLICK HERE

Thursday, 5 April 2018

Industry IoT Technology 4.0

                                                 
The RDL-5000 series defines a new way of transforming factories into smart/intelligent factories, aiming to better serve customers through greater flexibility of production and optimization of resources by implementing the IIoT 4.0.

Benefits :
·         Improving operational efficiency.
·         Improving productivity.
·         Creating new business opportunities.
·         Reducing downtime.
·         Maximizing asset utilization.
·         Tracking behavior for real-time marketing.
·         Enhanced situational awareness.
·         Sensor-driven decision analytics.
·         Instantaneous control and response in complex autonomous systems.
Features:
·         Wireless RS485 Modbus RTU.
·         MQTT and RESTful API IoT Protocol Support.
·         Cloud Storage.
·         Sub-GHz interface.
·         Supports for WiFi 2.4GHz.
Applications :
·         Smart home.                           
·         Wearables.
·         Smart City.
·         Smart grids.
·         Industrial internet.
·         Connected car.
·         Environmental monitoring.
·         Connected Health.
·         Smart retail.
·         Smart supply chain.
·         Smart farming.
For More Schematic and Samples: CLICK HERE