Arduino MEGA, LCD and SSR is frozen after 24 hours - arduino

I'm going to tell you my problem with arduino.
I am making an access rfdi system to enable a water pump, the procedure is as follows: I bring the rfid keyring closer to the reader, I make a sql query to the server and if it returns the data, I enable the pump and later register that user is served water.
Everything works fine for 18-24 hours, after that time the screen freezes and the arduino doesn't respond in any way or run the program. To get it to work again I have to restart it.
Maybe I thought it was a memory problem, but I don't know. On build I have Sketch (18%) and memory (22%).
I don't know where the problem is.
#include <U8glib.h>
#include <SPI.h>
#include <EthernetENC.h>
#include <Wiegand.h> //PROTOCOLO P/ RFDI
#include <ArduinoJson.h>
U8GLIB_ST7920_128X64_1X u8g(6, 5, 4 ,7); //LCD Enable, RW, RS, RESET
#define FALSE 0
#define TRUE 1
long int rawToken;
char c;
char pageAdd[64];
char user[64];
int totalCount = 0;
String ID = "";
String readString = "";
String clientegraba = "";
String terrenograba = "";
bool inicio = true;
bool errorbit = false;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// CONFIG IP ARDUINO
IPAddress ip(192,168,0,210);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);
// IP Y PUERTO SERVIDOR
IPAddress server(192,168,0,104);
char serverName[] = "192.168.0.104";
int serverPort = 80;
EthernetClient client;
WIEGAND wg;
void setup() {
Serial.begin(9600);
pinMode(34,OUTPUT); //OUT PUMP
digitalWrite(34,LOW);
welcome(); //PANTALLA BIENVENIDA
//GATE A
wg.D0PinA =2;
wg.D1PinA =3;
//GATE B
wg.D0PinB =18;
wg.D1PinB =19;
//GATE C
wg.D0PinC =20;
wg.D1PinC =21;
// Reader enable
wg.begin(TRUE, FALSE, FALSE); // wg.begin(GateA , GateB, GateC)
// disable SD SPI
pinMode(4,OUTPUT);
digitalWrite(4,HIGH);
// Start ethernet
Serial.println(F("Iniciando ethernet..."));
Ethernet.begin(mac, ip, gateway, gateway, subnet);
Serial.println(Ethernet.localIP());
delay(2000);
Serial.println(F("Listo"));
ingresellave();
}
void loop()
{
if(wg.available()){
errorbit = false;
espere(); //WAITING SCREEN
ID = String(wg.getCode()); //OBTIENE ID DE TARJETA
String data = "/test.php?cliente=" + ID; //CONCAT ID
sprintf(pageAdd,data.c_str(),totalCount);
Serial.println(pageAdd);
if(!getPage(server,serverPort,pageAdd)){
Serial.print(F("Falla "));
}else{
Serial.print(F("Paso "));
}
totalCount++;
Serial.println(totalCount,DEC);
}
if(ID != ""){
if(clientegraba != ""){
grabacarga(clientegraba,terrenograba);
}else{
if(errorbit == false){
noexiste();
delay(3000);
ID = "";
ingresellave();
}
}
}
delay(200);
}
byte getPage(IPAddress ipBuf,int thisPort, char *page)
{
int inChar;
char outBuf[128];
Serial.print(F("Conectando..."));
if(client.connect(ipBuf,thisPort) == 1){
Serial.println(F("Conectado"));
sprintf(outBuf,"GET %s HTTP/1.1",page);
client.println(outBuf);
sprintf(outBuf,"Host: %s",serverName);
client.println(outBuf);
client.println(F("Connection: close\r\n"));
}else{
error();
errorbit = true;
Serial.println(F("Error en servidor"));
return 0;
}
// connectLoop controls the hardware fail timeout
int connectLoop = 0;
boolean reader = false;
while(client.connected())
{
while(client.available())
{
String line = client.readStringUntil('\n');
if(reader){
StaticJsonBuffer<200> jsonBuffer;
JsonObject& datos = jsonBuffer.parseObject(line);
String apellido = datos["name"];
String cliente = datos["cliente"];
clientegraba = cliente;
long total = datos["total"];
long libres = datos["libres"];
String terreno = datos["terreno"];
terrenograba = terreno;
String costo = datos["costo"];
float price = costo.toFloat();
usuario(apellido,total,libres,price);
Serial.println("User: " + apellido);
Serial.println("Cliente: " + cliente);
Serial.println("Tarjeta: " + ID);
Serial.println("Terreno: " + terreno);
Serial.println("Costo: " + String(costo));
Serial.println("Total: " + String(total));
Serial.println("Libres: " + String(libres));
if(apellido != ""){
digitalWrite(34,HIGH); //PUMP START
delay(1000);
digitalWrite(34,LOW); //PUMP STOP
}
}
if(line == "\r") {
reader = true;
break;
}
// set connectLoop to zero if a packet arrives
connectLoop = 0;
}
connectLoop++;
// if more than 10000 milliseconds since the last packet
if(connectLoop > 10000)
{
// then close the connection from this end.
Serial.println();
Serial.println(F("Timeout"));
client.stop();
}
// this is a delay for the connectLoop timing
delay(1);
}
Serial.println();
Serial.println(F("Desconectando."));
// close client end
client.stop();
delay(100);
return 1;
}
void grabacarga(String cliente, String terreno){
String data = "/graba.php?cliente=" + cliente + "&tarjeta=" + ID + "&terreno='" + terreno + "'";
sprintf(pageAdd,data.c_str(),totalCount);
Serial.println(pageAdd);
if(!getPage(server,serverPort,pageAdd)) Serial.print(F("Falla "));
else Serial.print(F("Paso "));
totalCount++;
Serial.println(totalCount,DEC);
ID = "";
terrenograba = "";
clientegraba = "";
inicio = true;
delay(9000);
ingresellave();
}
void welcome() {
u8g.setRot180();
u8g.setFont(u8g_font_unifont);
u8g.firstPage();
do {
u8g.drawStr(18,22,"SISTEMA");
u8g.drawStr(15,50,"ACCESO RFID");
} while( u8g.nextPage() );
}
void ingresellave() {
u8g.setFont(u8g_font_unifont);
u8g.firstPage();
do {
u8g.drawStr(0,10,"COLOQUE EL BIDON");
u8g.drawStr(2,35,"Y LUEGO INGRESE");
u8g.drawStr(25,60,"UNA LLAVE");
} while( u8g.nextPage() );
}
void error() {
u8g.setFont(u8g_font_unifont);
u8g.firstPage();
do {
u8g.drawStr(40,10,"ERROR");
u8g.drawStr(33,35,"INTENTE");
u8g.drawStr(22,60,"NUEVAMENTE");
} while( u8g.nextPage() );
}
void espere() {
u8g.setFont(u8g_font_unifont);
u8g.firstPage();
do {
u8g.drawStr(25,35,"ESPERE...");
} while( u8g.nextPage() );
}
void usuario(String user, long total, long libres, float costo) {
u8g.firstPage();
do {
u8g.setFont(u8g_font_6x10);
u8g.drawStr(0,10,user.c_str());
String carga = "Carga:" + String(total) + "/" + String(libres);
u8g.setFont(u8g_font_unifont);
u8g.drawStr(15,33,carga.c_str());
if(total > libres){
long precio = total - libres;
float costototal = precio * costo;
Serial.println(costototal);
String valor = "Costo:$" + String(costototal);
u8g.drawStr(0,60,valor.c_str());
}
} while( u8g.nextPage() );
}
void noexiste(){
u8g.setFont(u8g_font_unifont);
u8g.firstPage();
do {
u8g.drawStr(34,22,"USUARIO");
u8g.drawStr(12,50,"NO REGISTRADO");
} while( u8g.nextPage() );
}
The system power is from a 12V 4.5A source and the Arduino Mega along with the screen(LCD12864A) are powered from the 5V pin through an external LM2596 regulator.
The screen data pins are connected to pins 4,5,6 and 7, the rfid reader to pins 2 and 3 and the water pump output is pin 34 which has a 2222a pnp transistor connected with a 1K base resistor, emitter to ground and collector to an SSR-24DA solid state relay.
Thank you.

After reading your comment mentioning wiegand malfunction, and the fact that it only malfunctioned after several hours of running well, I would try and see if it's overheating somehow, or try and reduce EMI by using EMI filter on the power supply and shielding the circuit board with aluminium box or the like.
Water pump can cause high EMI and voltage spike in the mains upon turning on or off.

Related

ESP32: Add micro sd card reader on 2nd SPI bus

I am trying to create a music box for my son, but i am having some trouble getting the SD card to work.
The idea is that when we scan a RFID tag we should get the corresponding mp3 file from the SD card.
I am using:
a ESP32 DOIT DEVKIT V1
RFID reader is a RFID-RC522
Micro SD card reader has no brand or model number on it. It just says "Micro sd card adapter" on the back and has 6 pins: cs, sck, mosi, miso, vcc, gnd
My problem is that both the RFID reader and the Micro SD Card reader should use SPI.
With the following code the RFID Card is working well. I just have no idea on how to add the SD Card reader (i have tried using the same pins as the rfid reader and also the HSPI pins, but without success!)
Any help is much appreciated!
#include <SPI.h>
#include <MFRC522.h>
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <WebSocketsServer.h>
#include <ArduinoJson.h>
#include "web_index.h"
// Constants
const char *ssid = "****";
const char *password = "****";
const int dns_port = 53;
const int http_port = 80;
const int ws_port = 1337;
// Globals
AsyncWebServer server(80);
WebSocketsServer webSocket = WebSocketsServer(1337);
char msg_buf[10];
// Tag reader variables
#define RFID_RC522_RST_PIN 27
#define RFID_RC522_SDA_PIN 5
MFRC522 mfrc522(RFID_RC522_SDA_PIN, RFID_RC522_RST_PIN);
bool rfid_tag_present_prev = false;
bool rfid_tag_present = false;
int _rfid_error_counter = 0;
bool _tag_found = false;
// Volume Variables
int VOLUME = 15;
int VOLUME_NORMAL_MAX = 30;
int VOLUME_LIMIT_MAX = 15;
int VOLUME_MAX = VOLUME_NORMAL_MAX;
int VOLUME_MIN = 0;
int VOLUME_CHANGE_AMOUNT = 1;
bool VOLUME_IS_LIMITED = false;
// Player variables
bool IS_PLAYING = false;
String TRACK_NAME = "-";
String ARTIST_NAME = "-";
// Button variables
const int BUTTON_VOL_DOWN_PIN = 34;
bool BUTTON_VOL_DOWN_STATE = HIGH;
bool BUTTON_VOL_DOWN_PREV_STATE = HIGH;
const int BUTTON_VOL_UP_PIN = 35;
bool BUTTON_VOL_UP_STATE = HIGH;
bool BUTTON_VOL_UP_PREV_STATE = HIGH;
const int BUTTON_STOP_PIN = 32;
bool BUTTON_STOP_STATE = HIGH;
bool BUTTON_STOP_PREV_STATE = HIGH;
const int BUTTON_NEXT_PIN = 33;
bool BUTTON_NEXT_STATE = HIGH;
bool BUTTON_NEXT_PREV_STATE = HIGH;
// Tag IDs
String TAG_TEST = "93 44 5C 92";
String TAG_BACH = "9C CD 69 0F";
/***********************************************************
Functions
*/
void volumeDecrease() {
if (VOLUME > VOLUME_MIN) {
VOLUME = VOLUME - VOLUME_CHANGE_AMOUNT;
broadcastUpdate();
}
}
void volumeIncrease() {
if (VOLUME < VOLUME_MAX) {
VOLUME = VOLUME + VOLUME_CHANGE_AMOUNT;
broadcastUpdate();
} else {
VOLUME = VOLUME_MAX;
broadcastUpdate();
}
}
void updateVolumeLimitState(bool state) {
VOLUME_IS_LIMITED = state;
broadcastUpdate();
}
void broadcastUpdate() {
DynamicJsonDocument doc(1024);
doc["volume"] = VOLUME;
doc["volume_min"] = VOLUME_MIN;
doc["volume_max"] = VOLUME_MAX;
doc["volume_is_limited"] = VOLUME_IS_LIMITED;
doc["is_playing"] = IS_PLAYING;
doc["track_name"] = TRACK_NAME;
doc["artist_name"] = ARTIST_NAME;
char json_string[1024];
serializeJson(doc, json_string);
webSocket.broadcastTXT(json_string);
}
void handleWsTextMessage(uint8_t client_num, uint8_t * payload) {
if ( strcmp((char *)payload, "getValues") == 0 ) {
broadcastUpdate();
} else if ( strcmp((char *)payload, "volume_down_button_click") == 0 ) {
volumeDecrease();
} else if ( strcmp((char *)payload, "volume_up_button_click") == 0 ) {
volumeIncrease();
} else if ( strcmp((char *)payload, "volume_limit_checkbox_on") == 0 ) {
updateVolumeLimitState(true);
} else if ( strcmp((char *)payload, "volume_limit_checkbox_off") == 0 ) {
updateVolumeLimitState(false);
} else { // Message not recognized
Serial.println("[%u] Message not recognized");
}
}
// Callback: receiving any WebSocket message
void onWebSocketEvent(uint8_t client_num, WStype_t type, uint8_t * payload, size_t length) {
// Figure out the type of WebSocket event
switch (type) {
// Client has disconnected
case WStype_DISCONNECTED:
Serial.printf("[%u] Disconnected!\n", client_num);
break;
// New client has connected
case WStype_CONNECTED:
{
IPAddress ip = webSocket.remoteIP(client_num);
Serial.printf("[%u] Connection from ", client_num);
Serial.println(ip.toString());
}
break;
// Handle text messages from client
case WStype_TEXT:
// Print out raw message
Serial.printf("[%u] Received text: %s\n", client_num, payload);
handleWsTextMessage(client_num, payload);
break;
// For everything else: do nothing
case WStype_BIN:
case WStype_ERROR:
case WStype_FRAGMENT_TEXT_START:
case WStype_FRAGMENT_BIN_START:
case WStype_FRAGMENT:
case WStype_FRAGMENT_FIN:
default:
break;
}
}
// Callback: send homepage
void onIndexRequest(AsyncWebServerRequest *request) {
const char* dataType = "text/html";
IPAddress remote_ip = request->client()->remoteIP();
Serial.println("[" + remote_ip.toString() +
"] HTTP GET request of " + request->url());
// request->send(SPIFFS, "/index.html", "text/html");
AsyncWebServerResponse *response = request->beginResponse_P(200, dataType, index_html_gz, index_html_gz_len);
response->addHeader("Content-Encoding", "gzip");
request->send(response);
}
// Callback: send 404 if requested file does not exist
void onPageNotFound(AsyncWebServerRequest *request) {
IPAddress remote_ip = request->client()->remoteIP();
Serial.println("[" + remote_ip.toString() +
"] HTTP GET request of " + request->url());
request->send(404, "text/plain", "Not found");
}
/***********************************************************
Main
*/
void handleButtons() {
// VOLUME DOWN BUTTON
bool buttonVolDownState = digitalRead(BUTTON_VOL_DOWN_PIN);
if (buttonVolDownState == LOW && BUTTON_VOL_DOWN_PREV_STATE == HIGH) {
Serial.println("button down pressed");
volumeDecrease();
BUTTON_VOL_DOWN_PREV_STATE = LOW;
} else if (buttonVolDownState == HIGH && BUTTON_VOL_DOWN_PREV_STATE == LOW) {
BUTTON_VOL_DOWN_PREV_STATE = HIGH;
}
// VOLUME UP BUTTON
bool buttonVolUpState = digitalRead(BUTTON_VOL_UP_PIN);
if (buttonVolUpState == LOW && BUTTON_VOL_UP_PREV_STATE == HIGH) {
Serial.println("button up pressed");
volumeIncrease();
BUTTON_VOL_UP_PREV_STATE = LOW;
} else if (buttonVolUpState == HIGH && BUTTON_VOL_UP_PREV_STATE == LOW) {
BUTTON_VOL_UP_PREV_STATE = HIGH;
}
// STOP BUTTON
bool buttonStopState = digitalRead(BUTTON_STOP_PIN);
if (buttonStopState == LOW && BUTTON_STOP_PREV_STATE == HIGH) {
Serial.println("button stop pressed");
volumeIncrease();
BUTTON_STOP_PREV_STATE = LOW;
} else if (buttonStopState == HIGH && BUTTON_STOP_PREV_STATE == LOW) {
BUTTON_STOP_PREV_STATE = HIGH;
}
// NEXT BUTTON
bool buttonNextState = digitalRead(BUTTON_NEXT_PIN);
if (buttonNextState == LOW && BUTTON_NEXT_PREV_STATE == HIGH) {
Serial.println("button next pressed");
volumeIncrease();
BUTTON_NEXT_PREV_STATE = LOW;
} else if (buttonNextState == HIGH && BUTTON_NEXT_PREV_STATE == LOW) {
BUTTON_NEXT_PREV_STATE = HIGH;
}
}
String getTagUid() {
String content = "";
byte letter;
for (byte i = 0; i < mfrc522.uid.size; i++) {
content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
content.concat(String(mfrc522.uid.uidByte[i], HEX));
}
content.toUpperCase();
String tag_uid = content.substring(1);
Serial.println("Getting tag uid");
Serial.println(content.substring(1));
return content.substring(1);
}
void checkTagValidity(String tag_uid) {
if (tag_uid == TAG_TEST) {
Serial.println("BLUE TAG");
ARTIST_NAME = "Blue Tag";
TRACK_NAME = "Super Track name";
IS_PLAYING = true;
broadcastUpdate();
} else if (tag_uid == TAG_BACH) {
Serial.println("BACH");
} else {
Serial.println("UNKNOWN CARD: ");
Serial.print(tag_uid);
}
}
void setup() {
// Init buttons
pinMode(BUTTON_VOL_DOWN_PIN, INPUT_PULLUP);
pinMode(BUTTON_VOL_UP_PIN, INPUT_PULLUP);
pinMode(BUTTON_STOP_PIN, INPUT_PULLUP);
pinMode(BUTTON_NEXT_PIN, INPUT_PULLUP);
// Start Serial port
Serial.begin(115200);
// Init SPI bus (for the tag reader)
SPI.begin();
// Init the tag reader
mfrc522.PCD_Init();
// Start access point
WiFi.softAP(ssid, password);
// Print our IP address
Serial.println();
Serial.println("AP running");
Serial.print("My IP address: ");
Serial.println(WiFi.softAPIP());
// On HTTP request for root, provide index.html file
server.on("/", HTTP_GET, onIndexRequest);
// 404 page
server.onNotFound(onPageNotFound);
// Start web server
server.begin();
// Start WebSocket server and assign callback
webSocket.begin();
webSocket.onEvent(onWebSocketEvent);
}
void loop() {
// Check for button clicks
handleButtons();
// Look for and handle WebSocket data
webSocket.loop();
rfid_tag_present_prev = rfid_tag_present;
_rfid_error_counter += 1;
if (_rfid_error_counter > 2) {
_tag_found = false;
}
// Detect Tag without looking for collisions
byte bufferATQA[2];
byte bufferSize = sizeof(bufferATQA);
// Reset baud rates
mfrc522.PCD_WriteRegister(mfrc522.TxModeReg, 0x00);
mfrc522.PCD_WriteRegister(mfrc522.RxModeReg, 0x00);
// Reset ModWidthReg
mfrc522.PCD_WriteRegister(mfrc522.ModWidthReg, 0x26);
MFRC522::StatusCode result = mfrc522.PICC_RequestA(bufferATQA, &bufferSize);
if (result == mfrc522.STATUS_OK) {
if ( ! mfrc522.PICC_ReadCardSerial()) { //Since a PICC placed get Serial and continue
return;
}
_rfid_error_counter = 0;
_tag_found = true;
}
rfid_tag_present = _tag_found;
// rising edge
if (rfid_tag_present && !rfid_tag_present_prev) {
Serial.println("Tag found");
// Get tag uid
String tag_uid = getTagUid();
// Check if valid tag
checkTagValidity(tag_uid);
}
// falling edge
if (!rfid_tag_present && rfid_tag_present_prev) {
Serial.println("Tag gone");
ARTIST_NAME = "-";
TRACK_NAME = "-";
IS_PLAYING = false;
broadcastUpdate();
}
}
Thanks to the comments from #romkey and #RamyHx i got it to work using the same SPI pins.
My problem was that i was using the same pin for the CS of both devices. Once i change it to different CS pins for the rfid and sd card reader it started working.
For the RFID i have used the pin D2, and for the sd card reader i have used the pin D5.
For the rfid i have change #define RFID_RC522_SDA_PIN 5 into #define RFID_RC522_SDA_PIN 2.
For the sd card i have used the code here, which assumes we are using the default pins (with CS connected to pin D5).

Arduino TTL jpeg Serial Camera and esp8266 wifi Wi-Fi module

I'm writing a code to take pictures if the distance is more than a certain distance after measuring the distance.
And send the distance data to Thingspeak, Store the photos on the SD card.
However, the program keeps stopping in the middle.
Serial moniter capture
Distance measurement and Thingspeak server data transfer / camera shooting were developed separately.
The two source codes worked normally independently.
But when the two codes are combined, there is an error.
Parts for Use : Arduino Uno, esp8266 wifi module, TTL Serial JPEG Camera with NTSC Video, 2Y0A21 Infrared Distance Sensor, Micro SD card adapter
#include <SoftwareSerial.h>
#include <stdlib.h>
#include <Adafruit_VC0706.h>
#include <SPI.h>
#include <SD.h>
#define DEBUG true
#define chipSelect 10
const int distancePin = 0;
String apiKey = "39R00EYW0BTKK5JJ";
SoftwareSerial esp8266(2, 3); //TX/RX
#if ARDUINO >= 100
SoftwareSerial cameraconnection = SoftwareSerial(4, 5); //TX/RX
#else
NewSoftSerial cameraconnection = NewSoftSerial(4, 5);
#endif
Adafruit_VC0706 cam = Adafruit_VC0706(&cameraconnection);
int defaultDistance = 0;
int temp = 0;
void ThingspeakSendData(String alarmData);
void Snapshots();
void setup() {
#if !defined(SOFTWARE_SPI)
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
if (chipSelect != 53) pinMode(53, OUTPUT); // SS on Mega
#else
if (chipSelect != 10) pinMode(10, OUTPUT); // SS on Uno, etc.
#endif
#endif
Serial.begin(9600);
Serial.println("VC0706 Camera snapshot test");//the program keeps stopping in the middle.
if (cam.begin()) {
Serial.println("Camera Found:");
}
else {
Serial.println("No camera found?");
return;
}
char *reply = cam.getVersion();
if (reply == 0) {
Serial.print("Failed to get version");
}
else {
Serial.println("-----------------");
Serial.print(reply);
Serial.println("-----------------");
}
cam.setImageSize(VC0706_640x480);
uint8_t imgsize = cam.getImageSize();
Serial.print("Image size: ");
if (imgsize == VC0706_640x480) Serial.println("640x480");
if (imgsize == VC0706_320x240) Serial.println("320x240");
if (imgsize == VC0706_160x120) Serial.println("160x120");
esp8266.begin(9600);
sendData("AT+RST\r\n", 2000, DEBUG); //reset module
sendData("AT+CWMODE=1\r\n", 1000, DEBUG); //dual mode로 설정
sendData("AT+CWJAP=\"0sangsiljangnim\",\"123456788\"\r\n", 5000, DEBUG);
// 2Y0A21
analogReference(DEFAULT);
pinMode(distancePin, INPUT);
// distancePin 2Y0A21
int raw = analogRead(distancePin);
int volt = map(raw, 0, 1023, 0, 5000);
int distance = (21.61 / (volt - 0.1696)) * 1000;
defaultDistance = distance;
Serial.println("Default : " + defaultDistance);
}
void loop() {
// distancePin 2Y0A21
int raw = analogRead(distancePin);
int volt = map(raw, 0, 1023, 0, 5000);
int distance = (21.61 / (volt - 0.1696)) * 1000;
Serial.println(distance);
if (distance < defaultDistance)
{
String alarmData = "1";
esp8266.listen();
ThingspeakSendData(alarmData);
cameraconnection.listen();
Snapshots();
}
else if (distance == defaultDistance)
{
String alarmData = "0";
esp8266.listen();
ThingspeakSendData(alarmData);
}
delay(3000);
}
void ThingspeakSendData(String alarmData) {
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += "184.106.153.149";
cmd += "\",80";
esp8266.println(cmd);
if (esp8266.find("Error")) {
Serial.println("AT+CIPSTART error");
return;
}
String getStr = "GET /update?api_key=";
getStr += apiKey;
getStr += "&field1=";
getStr += String(alarmData);
getStr += "\r\n\r\n";
// Send Data
cmd = "AT+CIPSEND=";
cmd += String(getStr.length());
esp8266.println(cmd);
if (esp8266.find(">")) {
esp8266.print(getStr);
}
else {
esp8266.println("AT+CIPCLOSE");
// alert uesp8266
Serial.println("AT+CIPCLOSE");
}
}
String sendData(String command, const int timeout, boolean debug) {
String response = "";
esp8266.print(command);
long int time = millis();
while ((time + timeout) > millis()) {
while (esp8266.available()) {
char c = esp8266.read();
response += c;
}
}
if (debug) {
Serial.print(response);
}
return response;
}
void Snapshots() {
Serial.println("Snap in 3 secs...");
delay(3000);
if (!cam.takePicture())
Serial.println("Failed to snap!");
else
Serial.println("Picture taken!");
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
return;
}
char filename[13];
strcpy(filename, "IMAGE00.JPG");
for (int i = 0; i < 100; i++) {
filename[5] = '0' + i / 10;
filename[6] = '0' + i % 10;
if (!SD.exists(filename)) {
break;
}
}
File imgFile = SD.open(filename, FILE_WRITE);
uint16_t jpglen = cam.frameLength();
Serial.print("Storing ");
Serial.print(jpglen, DEC);
Serial.print(" byte image.");
int32_t time = millis();
pinMode(8, OUTPUT);
byte wCount = 0;
while (jpglen > 0) {
uint8_t *buffer;
uint8_t bytesToRead = min(32, jpglen);
buffer = cam.readPicture(bytesToRead);
imgFile.write(buffer, bytesToRead);
if (++wCount >= 64) {
Serial.print('.');
wCount = 0;
}
jpglen -= bytesToRead;
}
imgFile.close();
time = millis() - time;
Serial.println("done!");
Serial.print(time); Serial.println(" ms elapsed");
}

Error using thingspeak talk back to control arduino led

The error I'm facing is about using talkback function of thingspeak to control my Arduino LED. it cannot execute the talkback command to off the led. The error is in my void get talkback. Please help me
#include "ThingSpeak.h"
#include <Ethernet.h>
#define redLED 8
byte mac[] = {0x90, 0xA2, 0xDA, 0x10, 0x40, 0x4F};
const String channelsAPIKey = "";
const String talkBackAPIKey = "";
const String talkBackID = "";
const String talkCommandID = "";
const unsigned int getTalkBackInterval = 10 * 1000;
const unsigned int updateChannelsInterval = 15 * 1000;
String talkBackCommand;
long lastConnectionTimeChannels = 0;
boolean lastConnectedChannels = false;
int failedCounterChannels = 0;
long lastConnectionTimeTalkBack = 0;
boolean lastConnectedTalkBack = false;
int failedCounterTalkBack = 0;
char charIn;
// Arduino Ethernet Client is initialized
EthernetClient client;
void setup()
{
Ethernet.init(10); // Most Arduino Ethernet hardware
Serial.begin(9600); //Initialize serial
// start the Ethernet connection:
pinMode(redLED, OUTPUT);
digitalWrite(redLED, HIGH);
}
void loop()
{
getTalkBack();
}
void getTalkBack()
{
String tsData;
tsData = talkBackID + "/commands/execute?api_key=" + talkBackAPIKey;
if ((!client.connected() && (millis() - lastConnectionTimeTalkBack > getTalkBackInterval)))
{
if (client.connect("api.thingspeak.com", 80))
{
client.println("GET /talkbacks/" + tsData + " HTTP/1.0");
client.println();
lastConnectionTimeTalkBack = millis();
if (client.connected())
{
Serial.println("---------------------------------------");
Serial.println("GET TalkBack command");
Serial.println();
Serial.println("Connecting to ThingSpeak");
Serial.println();
Serial.println();
Serial.println("Server response");
Serial.println();
failedCounterTalkBack = 0;
while (client.connected() && !client.available()) delay(2000); //waits for data
while (client.connected() || client.available())
{
charIn = client.read();
talkBackCommand += charIn;
Serial.print(charIn);
if (talkBackCommand == "LED_ON")
{
digitalWrite(redLED, HIGH);
}
if (talkBackCommand == "LED_OFF")
{
digitalWrite(redLED, LOW);
}
}
if (talkBackCommand = talkBackCommand.substring(talkBackCommand.indexOf("_CMD_") + 5));
{
Serial.println();
Serial.println();
Serial.println("Disconnected");
Serial.println();
Serial.println("--------");
Serial.println();
Serial.println("talkback command was");
Serial.println();
Serial.println("--------");
Serial.println();
Serial.println(talkBackCommand);
Serial.println("--------");
Serial.println();
}
}
else
{
failedCounterTalkBack++;
Serial.println("Connection to ThingSpeak failed (" + String(failedCounterTalkBack, DEC) + ")");
Serial.println();
lastConnectionTimeChannels = millis();
}
}
}
if (failedCounterTalkBack > 3 )
{
startEthernet();
}
client.stop();
Serial.flush();
}
The below is a image from my serial monitor. It shows that I can capture the command but couldn't execute it.
Looks like you are reading and appending all the received bytes to talkBackCommand. So, talkBackCommand is "HTTP/1.1 200 OK Date...." and if (talkBackCommand == "LED_ON") would never be true.
I think you wanted to see if the received data contain your commands LED_ON or LED_OFF. You can do something like this:
if (talkBackCommand.indexOf("LED_ON") != -1)
indexOf() locates a String in a String and returns index or -1 if not found.
See more info about indexOf() here: https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/indexof/

ESP8266 - Response from server gets cut

I'm using an ESP8266 connected to an Arduino one via SoftwareSerial to make a post request to a node web server. The ESP8266 sends some data to the server and it should get back other data. The data arrives at the server correctly, but the response from the server is incomplete (it gets cut each time in a different way) and I can't access the body of the response from my Arduino sketch. The server sends the response correctly, as i've checked with hurl.
This is my code:
#include "SoftwareSerial.h"
String ssid ="ssid";
String password="pwd";
SoftwareSerial esp(3, 2);// RX, TX
ESP8266_Simple wifi(3,2);
String data;
String server = "server";
String uri = "uri";
String token = "token";
float temp_set = 15; //standard values
float temp_rec = 15;
String temp_set_s;
String temp_rec_s;
int activate = LED_BUILTIN; //pin for relay
int button_up = 4;
int button_down = 5;
unsigned long time;
//LCD
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
// DHT11
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#define DHTPIN 6
#define DHTTYPE DHT22
DHT_Unified dht(DHTPIN, DHTTYPE);
void setup() {
esp.begin(9600);
Serial.begin(9600);
delay(10);
reset();
connectWifi();
pinMode(activate, OUTPUT);
pinMode(button_up, INPUT);
pinMode(button_down, INPUT);
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
//DHT setup
dht.begin();
sensor_t sensor;
delay(500);
}
//reset the esp8266 module
void reset() {
esp.println("AT+RST");
delay(1000);
if(esp.find("OK") ) Serial.println("Module Reset");
}
//connect to your wifi network
void connectWifi() {
String cmd = "AT+CWJAP=\"" +ssid+"\",\"" + password + "\"";
esp.println(cmd);
delay(4000);
if(esp.find("OK")) {
Serial.println("Connected!");
time = millis();
} else {
connectWifi();
Serial.println("Cannot connect to wifi");
}
}
void loop () {
//temp_rec_s = String(temp_rec);
//temp_set_s = String(temp_set);
//data = "tempRec=" + temp_rec_s + "&tempSet=" + temp_set_s;
//httppost();
// dht data
sensors_event_t event;
dht.temperature().getEvent(&event);
temp_rec = event.temperature;
//temp_rec_s = String(temp_rec);
//temp_set_s = String(temp_set);
//data = "tempRec=" + temp_rec_s + "&tempSet" + temp_set_s;
// to activate
if(temp_set < temp_rec){
digitalWrite(activate, LOW);
} else{
digitalWrite(activate, HIGH);
}
//function for physical buttons
if((digitalRead(button_up)) == HIGH){
temp_set = temp_set + 0.5;
delay(100);
}
if((digitalRead(button_down)) == HIGH){
temp_set = temp_set - 0.5;
delay(100);
}
//shows temperature on display
lcd.setCursor(0, 0);
lcd.print("T rec " + String(temp_rec));
//shows temperature on display
lcd.setCursor(0, 1);
lcd.print("T set " + String(temp_set));
temp_rec_s = String(temp_rec);
temp_set_s = String(temp_set);
data = "tempRec=" + temp_rec_s + "&tempSet=" + temp_set_s + "&token=" + token;
//Serial.println(data);
if((millis() - time) >= 10000){
httppost();
}
delay(200);
}
void httppost () {
esp.println("AT+CIPSTART=\"TCP\",\"" + server + "\",80");//start a TCP connection.
if(esp.find("OK")) {
Serial.println("TCP connection ready");
}
delay(1000);
String postRequest =
"POST " + uri + " HTTP/1.0\r\n" +
"Host: " + server + "\r\n" +
"Accept: *" + "/" + "*\r\n" +
"Content-Length: " + data.length() + "\r\n" +
"Content-Type: application/x-www-form-urlencoded\r\n" +
"\r\n" + data;
String sendCmd = "AT+CIPSEND="; //determine the number of caracters to be sent.
esp.print(sendCmd);
esp.println(postRequest.length());
Serial.println(postRequest);
delay(500);
if(esp.find(">")) {
Serial.println("Sending..");
esp.print(postRequest);
String tmpResp = esp.readString();
Serial.println(tmpResp);
if(esp.find("SEND OK")) {
Serial.println("Packet sent");
while(esp.available()) {
String line = esp.readString();
Serial.print(line);
}
// close the connection
esp.println("AT+CIPCLOSE");
}
}
}
Put a delay(1) under the esp.readString() and use .read() instead with char like this:
while(esp.available())
{
char line = esp.read(); // read one char at a time
delay(1); // prevent freezing
Serial.print(line);
if (line == '\0') continue; // terminate the `while` when end of the data
}
The .readString() method as pointed out by #gre_gor reads until there is no incoming data for 1 second.
So the better method is to use read() and char since you can test the char to see if you have reached the end of data character \0.
When using .read() consider using a custom timeout, because data can be delivered with delays so you might want to keep trying for a certain period of time if you haven't yet reached the end of data character \0, like this:
long int time = millis(); // current time
long int wait = 1000 * 10; // wait 10 seconds before terminating the read process
while ((time + wait) > millis())
{
while (esp.available())
{
char line = esp.read();
delay(1);
Serial.print(line);
if (line == '\0') continue;
}
}

Alarm.alarmRepeat repeats only twice then stops working

I'm using an arduino uno with a CC3000 WiFi Shield. The ardunio counts people using a light barrier and then reports the countings to the xievly site. It seems to work fine for an hour or two but then nothing happens. Any ideas?
// Libraries
#include <Adafruit_CC3000.h>
#include <SPI.h>
#include <Time.h>
#include <TimeAlarms.h>
// Define CC3000 chip pins
#define ADAFRUIT_CC3000_IRQ 3
#define ADAFRUIT_CC3000_VBAT 5
#define ADAFRUIT_CC3000_CS 10
// Create CC3000 instances
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
SPI_CLOCK_DIV2); // you can change this clock speed
// WLAN parameters
#define WLAN_SSID "XX"
#define WLAN_PASS "XX"
#define WLAN_SECURITY WLAN_SEC_WPA2
// Xively parameters
#define WEBSITE "https://xively.com/feeds/XX"
#define API_key "XXX"
#define feedID "XXXX``"
uint32_t ip;
Adafruit_CC3000_Client client;
const unsigned long
connectTimeout = 15L * 1000L, // Max time to wait for server connection
responseTimeout = 15L * 1000L; // Max time to wait for data from server
// Visitor Counter
int anzahl =0;
int lastState=LOW;
const int inputPin = 2;
void setup()
{
// Initialize
attachInterrupt(0, count, RISING);
Serial.begin(115200);
if (!cc3000.begin())
{
while(1);
}
// Connect to WiFi network
cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
/* Wait for DHCP to complete */
while (!cc3000.checkDHCP())
{
delay(100);
}
unsigned long t = getTime();
cc3000.disconnect();
setTime(hour(t)+2,minute(t),second(t),month(t),day(t),year(t));
Alarm.alarmRepeat(9,59,59, Messung);
Alarm.alarmRepeat(10,59,59, Messung);
Alarm.alarmRepeat(11,59,59, Messung);
Alarm.alarmRepeat(12,59,59, Messung);
Alarm.alarmRepeat(13,59,59, Messung);
Alarm.alarmRepeat(14,59,59, Messung);
Alarm.alarmRepeat(15,59,59, Messung);
Alarm.alarmRepeat(16,59,59, Messung);
Alarm.alarmRepeat(17,59,59, Messung);
Alarm.alarmRepeat(18,59,59, Messung);
Alarm.alarmRepeat(19,59,59, Messung);
Alarm.alarmRepeat(22,59,59, Zeitkorrektur);
}
void count()
{
delay(10);
int val = digitalRead(inputPin);
if (val == HIGH && lastState==LOW)
{
anzahl++;
lastState=val;
}
else
{
lastState=val;
}
}
void Zeitkorrektur()
{
getTime();
}
void Messung()
{
datalog();
}
void loop()
{
Alarm.delay(1000);
}
// Minimalist time server query; adapted from Adafruit Gutenbird sketch,
// which in turn has roots in Arduino UdpNTPClient tutorial.
unsigned long getTime()
{
uint8_t buf[48];
unsigned long ip, startTime, t = 0L;
// Hostname to IP lookup; use NTP pool (rotates through servers)
if(cc3000.getHostByName("pool.ntp.org", &ip)) {
static const char PROGMEM
timeReqA[] = { 227, 0, 6, 236 },
timeReqB[] = { 49, 78, 49, 52 };
Serial.println(F("\r\nAttempting connection..."));
startTime = millis();
do {
client = cc3000.connectUDP(ip, 123);
} while((!client.connected()) &&
((millis() - startTime) < connectTimeout));
if(client.connected()) {
Serial.print(F("connected!\r\nIssuing request..."));
// Assemble and issue request packet
memset(buf, 0, sizeof(buf));
memcpy_P( buf , timeReqA, sizeof(timeReqA));
memcpy_P(&buf[12], timeReqB, sizeof(timeReqB));
client.write(buf, sizeof(buf));
Serial.print(F("\r\nAwaiting response..."));
memset(buf, 0, sizeof(buf));
startTime = millis();
while((!client.available()) &&
((millis() - startTime) < responseTimeout));
if(client.available()) {
client.read(buf, sizeof(buf));
t = (((unsigned long)buf[40] << 24) |
((unsigned long)buf[41] << 16) |
((unsigned long)buf[42] << 8) |
(unsigned long)buf[43]) - 2208988800UL;
Serial.print(F("OK\r\n"));
}
client.close();
}
}
if(!t) Serial.println(F("error"));
return t;
}
void datalog()
{
//noInterrupts();
// Connect to WiFi network
cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY);
/* Wait for DHCP to complete */
while (!cc3000.checkDHCP())
{
delay(100);
}
// Set the website IP
uint32_t ip = cc3000.IP2U32(216,52,233,120);
cc3000.printIPdotsRev(ip);
// Get data & transform to integers
int visitors = (int) anzahl/2; //Visitors going in and out therefore divided by 2
// Prepare JSON for Xively & get length
int length = 0;
String data = "";
data = data + "\n" + "{\"version\":\"1.0.0\",\"datastreams\" : [ {\"id\" : \"Visitors\",\"current_value\" : \"" + String(visitors) + "\"}]}";
length = data.length();
// Send request
Adafruit_CC3000_Client client = cc3000.connectTCP(ip, 80);
if (client.connected()) {
Serial.println("Connected!");
client.println("PUT /v2/feeds/" + String(feedID) + ".json HTTP/1.0");
client.println("Host: api.xively.com");
client.println("X-ApiKey: " + String(API_key));
client.println("Content-Length: " + String(length));
client.print("Connection: close");
client.println();
client.print(data);
client.println();
} else {
Serial.println(F("Connection failed"));
return;
}
Serial.println(F("-------------------------------------"));
while (client.connected()) {
while (client.available()) {
char c = client.read();
Serial.print(c);
}
}
client.close();
Serial.println(F("-------------------------------------"));
Serial.println(F("\n\nDisconnecting"));
cc3000.disconnect();
anzahl =0;
//interrupts();
}
In setup() you configured interrupt with RISING. That means that it fires when the pin goes from low state to high state. But in interrupt handler - count() you have strange logic which looks excessive since you already configured interrupt to fire only once on event.
Let's see what happens in count(). val will always be HIGH (well, considering only normal case, not glitches).. When the first interrupt comes lastState is LOW as initial value and we increment, but all successive calls will not because lastState is HIGH and never becomes LOW again.
So, to fix problem, we simply need to drop lastState because it's not needed
void count()
{
delay(10);
// avoiding glitches - check if it's still high
int val = digitalRead(inputPin);
if (val == HIGH)
anzahl++;
}

Resources