Hi Blynkers,
I am using ESP8266 with Arduino Mega.
Sometimes my hardware keeps disconnecting (like every 2 minutes). The debug messages shows the following when the hardware gets disconnected:
Cmd error
Cmd skipped:20
Cmd skipped:20
Cmd skipped:20
Ready (ping: 9925ms)
[198249] <[11|00]b[00]gver[00]0.3.8[00]h-beat[00]10[00]buff-in[00]256[00]dev
[198657] <[00]Arduino Mega[00]cpu[00]ATmega2560[00]con[00]ESP8266
[198964] <[00]build[00]Jul 11 2016 22:57:03[00]
24.19
[199950] <[14|00]c[00|0B]vw[00]2[00]24.188
0.00
[200192] <[14|00]d[00|0A]vw[00]3[00]8.200
[200456] >[14|09|AA|00]/
[200456] >pm[00]4[00]out[00]10[00]out[00]5[00]out[00]9[00]out[00]11[00]out[00]6[00]out[00|FC|FC|F8|FC|FC|FC]
[200530] Invalid pin 4 mode ďż˝ /
I have pin 4 defined as output as it’s controlled by a function, but at the same time I have a button in my application that controls the same pin for manual operation. Does this mean I need to change the pin definition?
By the way I am using the latest Blynk version which was released today.
Below is my code, hope someone can help me:
#define BLYNK_PRINT Serial // Defines the object that is used for printing
#define BLYNK_DEBUG // Optional, this enables more detailed prints
#include<stdlib.h>
#include <ESP8266_Lib.h> //for Blynk
#include <BlynkSimpleShieldEsp8266.h>//for Blynk
#include <SimpleTimer.h>//for Blynk
#include <OneWire.h> //for temp sensor
#include <DallasTemperature.h> //for temp sensor
SimpleTimer timer; //simple timer for Blynk
#define ONE_WIRE_BUS 8 //pin 8 is for temp sensor
#define BLYNK_PRINT Serial
OneWire oneWire(ONE_WIRE_BUS); //for temp sensor
DallasTemperature sensors(&oneWire); //for temp sensor
//WIFI details
#define SSID "............" //wifi network name
#define PASS "............" //wifi password
//STARTwater flow sensor-------------------------------------------
// which pin to use for reading the sensor? can use any pin!
#define FLOWSENSORPIN 7
#define TONE_PIN 6 // buzzer output is pin 6
// count how many pulses!
volatile uint16_t pulses = 0;
// track the state of the pulse pin
volatile uint8_t lastflowpinstate;
// you can try to keep time of how long it is between pulses
volatile uint32_t lastflowratetimer = 0;
// and use that to calculate a flow rate
volatile float flowrate;
// Interrupt is called once a millisecond, looks for any pulses from the sensor!
SIGNAL(TIMER0_COMPA_vect) {
uint8_t x = digitalRead(FLOWSENSORPIN);
if (x == lastflowpinstate) {
lastflowratetimer++;
return; // nothing changed!
}
if (x == HIGH) {
//low to high transition!
pulses++;
}
lastflowpinstate = x;
flowrate = 1000.0;
flowrate /= lastflowratetimer; // in hertz
lastflowratetimer = 0;
}
void useInterrupt(boolean v) {
if (v) {
// Timer0 is already used for millis() - we'll just interrupt somewhere
// in the middle and call the "Compare A" function above
OCR0A = 0xAF;
TIMSK0 |= _BV(OCIE0A);
} else {
// do not call the interrupt function COMPA anymore
TIMSK0 &= ~_BV(OCIE0A);
}
}
//END water flow sensor--------------------------------------------------------------
//Thingspeak settigs
#define IP "184.106.153.149" // thingspeak.com
String GET = "GET /update?key=...........................&";//Thingspeak update key
//SoftwareSerial monitor(10, 11); // define software monitor pins (RX, TX)
const int updateThingSpeakInterval = 16 * 1000; // Time interval in milliseconds to update ThingSpeak (number of seconds * 1000 = interval)
float tempC;
int selectedwateramount = 0; //for wc
int wcinp = 0; // water change in process
int waterChangeAmount = 0;
int skimmer = 4;
int returnPump = 5;
int reactors = 6;
int ATO = 11;
int wcDrainPump = 10;
int wcFillPump = 9;
int wcFloatSwitch = 3;
const long skimmerDelay = 10000;
float liters = 0;
String enteredstring;
String wcamount;
String wccommandString;
long lastConnectionTime = 0;
long previousMillis = 0; //for temp sensor to read every n second
char auth[] = "...............................................";//Blynk auth code
#define EspSerial Serial1//for Blynk
ESP8266 wifi(&EspSerial);//for Blynk
WidgetLCD lcd(V1); //define Blynk LCD
WidgetTerminal terminal(V5);
char ph_data[20];
byte ph_string_received=0;
byte ph_received_from_sensor=0;
String inputstring = ""; //a string to hold incoming data from the PC
String sensorstring = ""; //a string to hold the data from the Atlas Scientific product
boolean input_string_complete = false; //have we received all the data from the PC
boolean sensor_string_complete = false; //have we received all the data from the Atlas Scientific product
float pH; //used to hold a floating point number that is the pH
//++++++++++++++++++++++++++++++++++++++++++++++++++START SETUP++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void setup()
{
Serial.begin(9600);
Serial1.begin(9600); //wifi serial
Serial3.begin(9600); //PH serial
pinMode(skimmer, OUTPUT);
pinMode(returnPump, OUTPUT);
pinMode(reactors, OUTPUT);
pinMode(wcDrainPump, OUTPUT);
pinMode(wcFillPump, OUTPUT);
pinMode(ATO, OUTPUT);
pinMode(wcFloatSwitch, INPUT);
digitalWrite(skimmer, HIGH);
digitalWrite(returnPump, HIGH);
digitalWrite(reactors, HIGH);
digitalWrite(wcDrainPump, LOW);
digitalWrite(wcFillPump, LOW);
digitalWrite(ATO, LOW);
inputstring.reserve(10); //PH - set aside some bytes for receiving data from the PC
sensorstring.reserve(30); //PH - set aside some bytes for receiving data from Atlas Scientific product
Blynk.begin(auth, wifi, "UltraTech", "haidarzeenalinawisam");// for Blynk
sensors.begin();//Start Temperature sensor
sendDebug("AT");//test id WIFI is responding
//delay(5000);
if (Serial1.find("OK")) {
Serial.println("RECEIVED: OK");
//connectWiFi();// connect to WIFI
}
pinMode(FLOWSENSORPIN, INPUT);
//pinMode(3, INPUT); //sump high float switch
//pinMode(9, OUTPUT); //res pump
// pinMode(10, OUTPUT); // sump pump
digitalWrite(FLOWSENSORPIN, HIGH);
lastflowpinstate = digitalRead(FLOWSENSORPIN);
useInterrupt(true);
//timer.setInterval(1500L, sendTempToLcdBlynk);
timer.setInterval(5000L, sendTempToGraphBlynk);
//timer.setInterval(4000L, sendPHToLcdBlynk);
timer.setInterval(7500L, sendPHToGraphBlynk);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++END SETUP++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void serialEvent3() { //if the hardware serial port_3 receives a PH reading
sensorstring = Serial3.readStringUntil(13); //read the string until we see a <CR>
sensor_string_complete = true; //set the flag used to tell if we have received a completed string from the PH sensor
}
//++++++++++++++++++++++++++++++++++++++++++++++++++START VOID LOOP++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void loop() {
Blynk.run(); // run Blynk process
timer.run(); // Initiates SimpleTimer
delay(50);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++END VOID LOOP++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//@@@@@@@functions@@@@@@@@@@@functions@@@@@@@@@@@functions@@@@@@@@@@@functions@@@@@@@@functions@@@@@@@@@
//-------------START send temp Blynk------------//
void sendTempToGraphBlynk()
{
GetTemperature();
Serial.println(tempC);
char buffer[10]; //buffer for the temperature
String temperature = dtostrf(tempC, 4, 2, buffer); //convert the temperature to a string
Blynk.virtualWrite(2, tempC);
}
//-------------END send temp Blynk graph------------//
//-------------START send pH on Blynk graph------------//
void sendPHToGraphBlynk()
{
GetPH();
Serial.println(pH);
char pH_buffer[10]; //buffer for the ph
String pHstring = dtostrf(pH, 3, 2, pH_buffer); //convert the pH to a string
Blynk.virtualWrite(3, 8.2);
}
//-------------END send pH on Blynk graph------------//
//-------------Start Get Temperature Function------------//
void GetTemperature()
{
sensors.requestTemperatures(); // Send the command to get temperatures
tempC = sensors.getTempCByIndex(0);
// Serial3.print("t,"); //send temperature to pH circuit
// Serial3.print(tempC); //send temperature to pH circuit
// Serial3.print("\r"); //send CR to pH circuit
}
//-------------End Get Temperature Function------------//
//----------START---------Receive command from Blynk terminal and excute accordingly----------------------------------
BLYNK_WRITE(V5)
{
enteredstring = param.asStr();
wcamount = enteredstring.substring(13);
wccommandString = enteredstring.substring(0, 12);
waterChangeAmount = wcamount.toInt();
terminal.println(wcamount);
terminal.println(wccommandString);
if (String("water change") == wccommandString) {
changeWater(waterChangeAmount);
//terminal.println("I said: 'Polo'") ;
}
else if (String("hi") == param.asStr())
{
terminal.print("Hi Haidar enter a command please");
// changeWater(waterChangeAmount);
//
// wcinp=0;
}
else if (String("hi") == param.asStr())
{
terminal.print("Hi Haidar enter a command please");
// changeWater(waterChangeAmount);
//
// wcinp=0;
}
else if (String("help") == param.asStr())
{
terminal.println("You can enter the following commands:");
terminal.println("- water change #");
// changeWater(waterChangeAmount);
//
// wcinp=0;
}
else if (String("pumps off") == param.asStr())
{
pumpsOff();
}
else if (String("pumps on") == param.asStr())
{
pumpsOn();
}
else if (String("ph temp") == param.asStr())
{
for(int a=0; a<2; a++)
{
Serial3.print("t,101\r");
delay(500);
}
//if (sensor_string_complete == true) { //if a string from the Atlas Scientific product has been received in its entirety
// terminal.println(sensorstring);
//
// Serial.println(sensorstring);
// sensorstring = ""; //clear the string:
// sensor_string_complete = false;
//}
terminal.println("Received");
}
else if (String("cont ph reading on") == param.asStr())
{
for(int a=0; a<2; a++)
{
Serial3.print("c,1\r");
delay(500);
}
//if (sensor_string_complete == true) { //if a string from the Atlas Scientific product has been received in its entirety
// terminal.println(sensorstring);
//
// Serial.println(sensorstring);
// sensorstring = ""; //clear the string:
// sensor_string_complete = false;
//}
terminal.println("Received");
}
else if (String("cont ph reading off") == param.asStr())
{
for(int a=0; a<2; a++)
{
Serial3.print("c,0\r");
delay(500);
}
//if (sensor_string_complete == true) { //if a string from the Atlas Scientific product has been received in its entirety
// terminal.println(sensorstring);
//
// Serial.println(sensorstring);
// sensorstring = ""; //clear the string:
// sensor_string_complete = false;
//}
terminal.println("Received");
}
//else if (String("haidar") == param.asStr()) {
// terminal.println("Řيدر") ;
//
//terminal.println("I said: 'Polo'") ;
// }
else {
// Send it back
terminal.write(param.getBuffer(), param.getLength());
terminal.print(" is not a valid command, enter help to see available options");
terminal.println();
}
// Ensure everything is sent
terminal.flush();
}
//----------END---------Receive command from Blynk terminal and excute accordingly----------------------------------
//
//-----------------Start get PH function-----------------//
void GetPH() {
if (sensor_string_complete == true) { //if a string from the Atlas Scientific product has been received in its entirety
//Serial.println(sensorstring); //send that string to the PC's serial monitor
if (isdigit(sensorstring[0])) { //if the first character in the string is a digit
pH = sensorstring.toFloat(); //convert the string to a floating point number so it can be evaluated by the Arduino
}
}
sensorstring = ""; //clear the string:
sensor_string_complete = false; //reset the flag used to tell if we have received a completed string from the Atlas Scientific product
}
//-----------------End get PH function-----------------//
//
//-------------update thingspeak----------------------//
void updateTemp(String temperature, String pHstring) {
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
sendDebug(cmd);
delay(2000);
if (Serial1.find("Error")) {
Serial.print("RECEIVED: Error");
return;
}
//cmd = GET;
//cmd += "field1=";
//cmd += temperature;
//cmd += "&field2=";
//cmd += pHstring;
//cmd += "\r\n";
cmd = GET + "&field1=" + temperature + "&field2=" + pHstring + "\r\n";
Serial1.print("AT+CIPSEND=");
Serial1.println(cmd.length());
if (Serial1.find(">")) {
Serial.print(">");
Serial.print(cmd);
Serial1.print(cmd);
lastConnectionTime = millis();
} else {
sendDebug("AT+CIPCLOSE");
lastConnectionTime = millis();
}
if (Serial1.find("OK")) {
Serial.println("RECEIVED: OK");
} else {
Serial.println("RECEIVED: Error");
}
}
void sendDebug(String cmd) {
Serial.print("SEND: ");
Serial.println(cmd);
Serial1.println(cmd);
}
//-------------update thingspeak----------------------//
//
//
//------------Connect wifi---------------
boolean connectWiFi() {
Serial1.println("AT+CWMODE=1");
delay(2000);
String cmd = "AT+CWJAP=\"";
cmd += SSID;
cmd += "\",\"";
cmd += PASS;
cmd += "\"";
sendDebug(cmd);
delay(5000);
if (Serial1.find("OK")) {
Serial.println("RECEIVED: OK");
return true;
} else {
Serial.println("RECEIVED: Error");
return false;
}
}
//------------Connect wifi---------------
//------START Water change function---------------------
void changeWater (int selectedwateramount)
{
terminal.println(selectedwateramount);
pulses = 0; //added code witout testing
liters = 0; //added code witout testing
if (selectedwateramount > 0) {
terminal.print("System will change ") ;
terminal.print(waterChangeAmount);
terminal.println(" liters") ;
tone(2, 3000, 3000);
pumpsOff();
wcinp = 1;
terminal.println("Water change started...") ;
while (liters < selectedwateramount) {
Blynk.run(); // run Blynk process
liters = pulses; //flow sensor
liters /= 7.5; //flow sensor
liters /= 60.0; //flow sensor
//Serial.print(liters); Serial.println(" Liters");
terminal.println("Draining water");
terminal.print(liters);
terminal.print(" ltr ");
//lcd.setCursor(9, 1);
terminal.print(liters / selectedwateramount * 100);
terminal.println("%");
//switch on sump pump
digitalWrite(wcFillPump, LOW);
digitalWrite(wcDrainPump, HIGH);
delay(500);
}
wcFloatSwitch = digitalRead(3); //added code witout testing
while (liters >= selectedwateramount && wcFloatSwitch == LOW) {
Blynk.run(); // run Blynk process
wcFloatSwitch = digitalRead(3);
terminal.println("* Adding water *");
//switch on res pump
digitalWrite(wcFillPump, HIGH);
digitalWrite(wcDrainPump, LOW);
//blinking adding water text
delay(500);
}
if (wcFloatSwitch == HIGH) {
//delay(2000); to eliminate sensor sensitivity should be added later somehow
Blynk.run(); // run Blynk process
tone(2, 1000, 10000);
pulses = 0;
liters = 0;
selectedwateramount = 0;
digitalWrite(wcFillPump, LOW);
digitalWrite(wcDrainPump, LOW);
pumpsOn();
terminal.println("Water change completed");
wcinp = 0;
}
}
else {
terminal.println("Please enter a valid amount");
}
}
void pumpsOff()
{
digitalWrite (skimmer,LOW);
digitalWrite (returnPump,LOW);
digitalWrite (reactors,LOW);
digitalWrite (ATO,LOW);
terminal.println("Pumps are off");
}
void pumpsOn()
{
int switchedOn = 0;
digitalWrite (returnPump,HIGH);
digitalWrite (reactors,HIGH);
terminal.println("Return pump and reactors switched on");
unsigned long pumpsOnTime = millis();
terminal.println("Switching on skimmer");
while (switchedOn !=1)
{
unsigned long skimmerOnTime = millis();
if (skimmerOnTime - pumpsOnTime >= skimmerDelay) {
Blynk.run(); // run Blynk process
digitalWrite (skimmer,HIGH);
switchedOn =1;
terminal.println("Skimmmer switched on");
}
}
}
//------END Water change function---------------------