Teensy LC & ESP8266 & Blynk

Tested another project using a Teensy LC & ESP8266 to get data to Blynk.
In the Teensy LC I used a library called EasyTransfer that will send a package of data to the ESP8266 through serial port. The ESP8266 is programmed as ESP8266Stand Alone and receives the data from the Teensy LC and passes it to the Blynk App. The Teensy doesn’t need any special programming for Blynk. I’m sure it could be used for any micro.
Just thought I would share this incase anyone would like to use Teensy & Blynk and would expect to have a Blynk sketch for the Teensy.

1 Like

Thanks for sharing! If you would add screenshots and code, that would be super helpful for someone looking for something similar.

Here’s a screen shot. It was a simple project just to see how it looked. I’ll add the code later since I’m not at my laptop right now.

Here is a copy of the Teensy LC code. I still need to do some clean-up and changes but it works and shows how the serial transfer works.

#include <LiquidCrystalFast.h>
#include <Bounce2.h>
#include <EEPROM.h>
#include <EasyTransfer.h>
#include <OneWire.h>

EasyTransfer Rx;
EasyTransfer Tx;

struct RECEIVE_DATA_STRUCTURE{byte data1;};
struct SEND_DATA_STRUCTURE{
  uint8_t Pump_Sta;
  uint16_t Last_Run;
  uint16_t Max_Run;
  boolean Sump_Al;
  uint16_t etime; 
  uint16_t temp;
  byte timer; 
};

RECEIVE_DATA_STRUCTURE Rxdata;
SEND_DATA_STRUCTURE Txdata;

#define RS 17
#define RW 18
#define E 19
#define D4 20
#define D5 21
#define D6 22
#define D7 23
#define UP 4   
#define DOWN 3  
#define ENT 2
#define BOOTLOADER 12
//Adjustable
#define PS 8
#define PUMP 5
#define LED 13
#define SUMP 7
#define therm 11

LiquidCrystalFast lcd(RS, RW, E, D4, D5, D6, D7);
OneWire ds(therm);

byte Sensor[8] ={0x28,0xFF,0x9A,0xA4,0x50,0x14,0x04,0x28};//28 FF 9A A4 50 14 4 28

uint8_t Pump_Sta = 0;  //Passed to Wifi
uint16_t Last_Run = 0;  //Passed to Wifi
uint16_t Max_Run = 0;  //Passed to Wifi
boolean Sump_Al = 0;  //Passes to Wifi
uint8_t Menu = 0;
uint8_t temp = 23; //Passed to Wifi
boolean Adj = 0;
boolean BL = 0;
//uint16_t counts = 0;
boolean LED_Sta = 1;
byte dump = 0;
uint16_t etime = 0;  //Passed to Wifi

uint16_t Display_Interval = 250;
unsigned long Display_Last = millis();
uint16_t Switch_Interval = 500;
unsigned long Switch_Last = millis()+100;
unsigned long Timer_Interval = EEPROM.read(1)*60000;
unsigned long Timer_Last;
unsigned long EEPROM_Interval = 300000;
unsigned long EEPROM_Last = millis();
unsigned long Return_Interval = 300000;
unsigned long Return_Last = 0;
//unsigned long Send_Interval = 1000;
//unsigned long Send_Last = millis();
unsigned long Temp_Interval = 1500;
unsigned long Temp_Last = millis();

unsigned long currentMillis = millis();

Bounce Inc = Bounce(); 
Bounce Dec = Bounce();
Bounce Ent = Bounce();
Bounce Ps = Bounce();
Bounce Sump = Bounce();

int get_Temperature(byte addr[8]){
byte i, dat;
byte data[12];

ds.reset();
ds.select(addr);
// Start conversion
ds.write(0x44);

dat = ds.read();
while (!dat){
  dat = ds.read();
}
ds.reset();
ds.select(addr);
// Issue Read scratchpad command
ds.write(0xBE);
// Receive 9 bytes
for ( i = 0; i < 9; i++) {
data[i] = ds.read();}
unsigned int raw = ((data[1] << 8) + data[0]);
if (raw < 2048) {return raw / 16.00;}else{return -(~(raw - 1) / 16.00);}}

void dssetresolution(byte addr[8]) {
// Set configuration
ds.reset();
ds.select(addr);
ds.write(0x4E);         // Write scratchpad
ds.write(0);            // TL
ds.write(0);            // TH
ds.write(0x3F);         // Configuration Register 12bit=0X7F 11bit=0X5F 10bit= 0X3F
ds.write(0x48);         // Copy Scratchpad
}

 
void setup()
{ 
  Serial1.begin(115200);
  Serial.begin(115200);
  Rx.begin(details(Rxdata), &Serial1);
  Tx.begin(details(Txdata), &Serial1); 
  lcd.begin(16, 2); 
  pinMode(PUMP, OUTPUT);
  pinMode(LED, OUTPUT);
  pinMode(UP, INPUT_PULLUP);
  pinMode(DOWN, INPUT_PULLUP);
  pinMode(ENT, INPUT_PULLUP);
  pinMode(PS, INPUT_PULLUP);
  pinMode(SUMP, INPUT_PULLUP);
  pinMode(BOOTLOADER, INPUT_PULLUP);
  Inc.attach(UP);
  Inc.interval(10); // interval in ms
  Dec.attach(DOWN);
  Dec.interval(10); // interval in ms
  Ent.attach(ENT);
  Ent.interval(10); // interval in ms
  Ps.attach(PS);
  Ps.interval(500); // interval in ms 
  Sump.attach(SUMP);
  Sump.interval(500); // interval in ms 
  dssetresolution(Sensor);
  Menu_Change();
  digitalWrite(LED,LED_Sta);
  }

void loop() {

  if(BL==0&&digitalRead(BOOTLOADER)==0){BL_Routine();}
  else{BL=1;}
  
  currentMillis = millis();

  switch_update();

  if(Rx.receiveData()){Data_Received();}
  
  if(currentMillis - Display_Last >= Display_Interval){Display_Last = currentMillis;lcd_update();}

  if(currentMillis - Temp_Last >= Temp_Interval){Temp_Last = currentMillis;temp = get_Temperature(Sensor);LED_Sta=!LED_Sta;digitalWrite(LED,LED_Sta);}
  
  //if(currentMillis - Send_Last >= Send_Interval){Send_Last = currentMillis;Send_update();}

  if(currentMillis - Switch_Last >= Switch_Interval){Switch_Last = currentMillis;switch_check();}

  if(currentMillis - Timer_Last >= Timer_Interval && Pump_Sta == 1){Pump_Sta=2;stop_pump();Menu=0;Menu_Change();}

  if(currentMillis - EEPROM_Last >= EEPROM_Interval){EEPROM_Last = currentMillis;EEPROM.update(1, (Timer_Interval / 60000));}

  if(currentMillis - Return_Last >= Return_Interval && Menu!=0){Adj=0;Menu=0;Menu_Change();}
  
  //if(counts>=1000){LED_Sta=!LED_Sta;counts=0;digitalWrite(LED,LED_Sta);}else{counts++;}
}

void Menu_Change(void){
    Return_Last = currentMillis;
    lcd.clear();
    lcd.setCursor(0,0);
    switch(Menu){
    case 0: lcd.print("PUMP STATUS");break;
    case 1: lcd.print("TIMER SETTING");lcd.setCursor(3,1);lcd.print("MINUTES");break;
    case 2: lcd.print("LAST RUN");break;
    case 3: lcd.print("MAX RUN");break;
    case 4: lcd.print("SUMP STATUS");break;
    case 5: lcd.print("TEMPERATURE");lcd.setCursor(3,1);lcd.print("Deg C");break;
    case 99: lcd.print("BOOTLOADER");break;
  } 
}

void lcd_update(void){
     etime=(millis()-Timer_Last)/600;
     lcd.setCursor(0,1);
     switch(Menu){
      case 0: switch(Pump_Sta){
               case 0: lcd.print("STOPPED         ");
                       break;
               case 1: lcd.print("RUNNING ");
                       print_dec(etime);
                       break;
               case 2: lcd.print("LOCKOUT         ");
                       break;        
               }
               break;
                    
      case 1: uint8_t value;
              value=Timer_Interval/60000;
              if(value<10){lcd.print(" ");}
              lcd.print(value);
              if(Adj==1){lcd.print("<");}
              else{lcd.print(" ");}
              break;
                  
      case 2: print_dec(Last_Run);
              break;

      case 3: print_dec(Max_Run);
              break;

      case 4: if(Sump_Al==1){lcd.print("HIGH  ");}
              else{lcd.print("NORMAL");}
              break;

      case 5: if(temp<10){lcd.print(" ");} 
              lcd.print(temp);
              break;     
}
}

void print_dec(uint16_t value){
  uint16_t x;
  lcd.print(value/100);
  lcd.print(":");
  x=value%100;
  x=x*6;
  x=x/10;
  if(x<10){lcd.print("0");}
  lcd.print(x);
  lcd.print(" ");
}

void start_pump(void){
  Pump_Sta=1;
  digitalWrite(PUMP,1);
  Timer_Last=millis();
}

void stop_pump(void){
  digitalWrite(PUMP,0);
  Last_Run=(millis()-Timer_Last)/600;
  if(Last_Run>Max_Run){Max_Run=Last_Run;}
}

void switch_update(void){
  Inc.update();
  Dec.update();
  Ent.update();
  Ps.update();
  Sump.update();
}

void switch_check(void){
  
  boolean value1 = Inc.read();
  boolean value2 = Dec.read();
  boolean value3 = Ent.read();
  boolean value4 = Ps.read();
  boolean value5 = Sump.read();

    if(value4==0&&Pump_Sta==0){start_pump();}
    if(value4==1&&Pump_Sta==1){Pump_Sta=0;stop_pump();}

    if(value5==0){Sump_Al=1;if(Menu!=4){Menu=4;Menu_Change();}}
    if(value5==1){Sump_Al=0;}

    switch(Menu){
      case 0: if(value1==0){Menu=5;Menu_Change();}
              if(value2==0){Menu=1;Menu_Change();}
              if(value3==0&&Pump_Sta==2){Pump_Sta=0;}
              break;
      case 1: if(value1==0&&Adj==0){Menu=0;Menu_Change();}
              if(value2==0&&Adj==0){Menu=2;Menu_Change();}
              if(value3==0&&Adj==0){Adj=1;break;}   

              if(value1==0&&Adj==1){if(Timer_Interval<=5880000){Timer_Interval+=60000;}}
              if(value2==0&&Adj==1){if(Timer_Interval>=360000){Timer_Interval-=60000;}}
              if(value3==0&&Adj==1){Adj=0;}
              break;
      case 2: if(value1==0){Menu=1;Menu_Change();}
              if(value2==0){Menu=3;Menu_Change();}
              if(value3==0){Last_Run=0;}   
              break;
      case 3: if(value1==0){Menu=2;Menu_Change();}
              if(value2==0){Menu=4;Menu_Change();}
              if(value3==0){Max_Run=0;}
              break;      
      case 4: if(value1==0){Menu=3;Menu_Change();}
              if(value2==0){Menu=5;Menu_Change();}
              break;      
      case 5: if(value1==0){Menu=4;Menu_Change();}
              if(value2==0){Menu=0;Menu_Change();}
              break;                              
    }
   
    }

void Data_Received (void){
  dump=Rxdata.data1;
  switch (dump){
    case 0:break;
    case 1:if(Timer_Interval<=5880000){Timer_Interval+=60000;}break;
    case 2:if(Timer_Interval>=360000){Timer_Interval-=60000;}break;
  }

  Txdata.Pump_Sta=Pump_Sta;
  Txdata.Last_Run=Last_Run;
  Txdata.Max_Run=Max_Run;
  Txdata.Sump_Al=Sump_Al;
  Txdata.etime=etime;
  Txdata.temp=temp;
  Txdata.timer=Timer_Interval/60000;
  Tx.sendData();     
}
    
void BL_Routine(void){
  Menu=99;
  Menu_Change();
  digitalWrite(LED, 1);
  delay(500);
  digitalWrite(LED, 0);
  while(1){
    if (Serial.available() > 0) {
    char ch = Serial.read();
    Serial1.print(ch);
  }
  if (Serial1.available() > 0) {
    char ch = Serial1.read();
    Serial.print(ch);
  }
  }
  
}

Here is a copy of the ESP8266 code.

//#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <EasyTransfer.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>

EasyTransfer Rx;
EasyTransfer Tx; 
SimpleTimer timer;

struct RECEIVE_DATA_STRUCTURE{
  uint8_t Pump_Sta;
  uint16_t Last_Run;
  uint16_t Max_Run;
  boolean Sump_Al;
  uint16_t etime;  
  uint16_t temp;
  byte timer;
};

struct SEND_DATA_STRUCTURE{byte data1;};

RECEIVE_DATA_STRUCTURE Rxdata;
SEND_DATA_STRUCTURE Txdata;

// variables
char auth[] = "";
const char* ssid     = "High Country";
const char* password = "";
byte cmd = 0;
String str = "";
byte count = 0;

void updateData(){
  
  Txdata.data1=cmd;
  Tx.sendData();
  unsigned long timeout = millis() + 200;
  for ( ; millis() < timeout;) {if(Rx.receiveData()) {break;}}
    
  switch(count){
    
  case 0:  switch(Rxdata.Pump_Sta){
           case 0: str="Off";break;
           case 1: str=String((float)Rxdata.etime/100);break;
           case 2: str="LOCK";break;
           }
           Blynk.virtualWrite(V0,str);
           break;
  case 1:  if(Rxdata.Sump_Al==0){str="Norm";}
           else{str="HIGH";}
           Blynk.virtualWrite(V1, str);
           break;
  case 2:  Blynk.virtualWrite(V2, (float)Rxdata.Last_Run/100);
           break;
  case 3:  Blynk.virtualWrite(V3, (float)Rxdata.Max_Run/100);
           break;
  case 4:  Blynk.virtualWrite(V4, Rxdata.timer);
           break;
  case 5:  Blynk.virtualWrite(V5, Rxdata.temp);
           break;
  }
  if(count==5){count=0;}
  else{count++;}
  cmd=0;
}

BLYNK_WRITE(V6){if(param.asInt()==1){cmd=1;count=4;updateData();}}
BLYNK_WRITE(V7){if(param.asInt()==1){cmd=2;count=4;updateData();}}

void setup() {
  Serial.begin(115200);
  Rx.begin(details(Rxdata), &Serial);
  Tx.begin(details(Txdata), &Serial);
  Blynk.begin(auth, ssid, password);

  timer.setInterval(250L, updateData);
}

void loop() {
  
  Blynk.run();
  timer.run(); // Initiates SimpleTimer
  if(Rx.receiveData()){}
  
}

Hope this helps someone.

2 Likes