Arduino Ethernet Client Server communication problem - tcp

This is my code:
#include <Keypad.h>
#include <LiquidCrystal.h>
#include <Ethernet.h>
#include <SPI.h>
bool hands = false;
bool result = true;
char Key;
unsigned int Number=0;
String weight;
String path;
bool alreadyConnected = false; // whether or not the client was connected previously
int cnt=0;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //physical mac address
byte ip[] = { 192, 168, 1, 2 }; // ip in lan
byte gateway[] = { 192, 168, 1, 1 }; // internet access via router
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
LiquidCrystal lcd(35, 34, 33, 32, 31, 30);
EthernetServer server(9639); //server port
EthernetClient client;
char keys[4][4] = {
{'1', '2', '3','A'},
{'4', '5', '6','B'},
{'7', '8', '9','C'},
{'*', '0', '#','D'},
};
byte rowpins[4] = {22, 23, 24, 25};
byte colpins[4] = {26, 27, 28, 29};
Keypad mykeypad = Keypad(makeKeymap(keys), rowpins, colpins, 4, 4);
String readString;
void setup()
{
lcd.begin(20, 4);
Ethernet.begin(mac, ip, gateway, subnet);
if (Ethernet.linkStatus() == LinkOFF) {
lcd.setCursor(0, 0);
lcd.print(" :Error: ");
lcd.setCursor(0, 1);
lcd.print("Ethernet Cable");
lcd.setCursor(0, 2);
lcd.print("Not Connected!");
Serial.println("Ethernet cable is not connected.");
while(true);
}
Serial.begin(19200);
Serial1.begin(19200);
EthernetClient client = server.available();
lcd.setCursor(0, 1);
lcd.print(" Connecting... ");
delay(5000);
if (client.connect(gateway, 9639))
{
client.print("A");
Serial.println("Connecting MilkyWeigh Server...");
}
else
{ lcd.clear();
lcd.setCursor(0, 1);
lcd.print("1.Check LAN Cable");
lcd.setCursor(0, 2);
lcd.print(" --Reset MilkoSol-- ");
while (true);
}
server.begin();
while (true) {
client = server.available(); // wait for a new client:
if (client)
{
while (client.connected())
{
if (client.available())
{
char b = client.read();
if (b == 'B')
{
lcd.setCursor(0, 2);
lcd.print(" Connected! ");
Serial.println("Successfully Connected!");
delay(1500);
hands = true;
b = "";
} //if B comes, handshaking done
} // if client available
} //while client connected
} //if (client)
if (hands == true)
{
lcd.clear();
client.stop();
break;
}
} //while true
lcd.setCursor(0, 0);
lcd.print ("Input Code: ");
lcd.print (Number);
} // void setup
void loop()
{
while (Key == NO_KEY){
Key = mykeypad.getKey();
}
DetectButtons();
if (Key == '4')
{
SaveToServer();
delay(200);
SaveToServer();
}
if (Key == '#')
{
if (Number > 0)
{
GetName();
}
Getweight();
}
Key=NO_KEY;
}
void Getweight(){
while (Serial1.available()>0)
{
weight = Serial1.readStringUntil('\r');
Serial1.flush();
}
Serial.print(weight);
}
void SaveToServer()
{
if (client.connect(gateway, 9639))
{
client.print('#'+String(Number)+','+weight);
//client.stop();
}
else
{ lcd.clear();
lcd.setCursor(0, 2);
lcd.print(" Save Error ");
Serial.println("Try again!");
Number=0;
readString="";
// weight="";
alreadyConnected=false;
return 0;
}
server.begin();
EthernetClient client = server.available(); // Listening for client (i.e. server) response
if (client)
{
if (!alreadyConnected)
{
// clear out the input buffer:
client.flush();
alreadyConnected = true;
}
while (client.connected())
{
if (client.available())
{
if (client.available()>0)
{
char z = client.read();
if (z == 'K')
{
Serial.print("Success: Data Saved!");
lcd.clear();
lcd.setCursor(6, 2);
lcd.print("Success!");
delay(1500);
Number=0;
weight="";
readString="";
DisplayResult();
}
client.flush();
client.stop();
}
}
}
} // if client
}// SaveToServer
void GetName()
{
if (client.connect(gateway, 9639))
{
client.print(Number);
//client.stop();
}
else
{ lcd.clear();
lcd.setCursor(0, 2);
lcd.print(" Connection Failed! ");
Serial.println("Connection Failed!");
Number=0;
readString="";
// weight="";
alreadyConnected=false;
return 0;
}
server.begin();
EthernetClient client = server.available(); // Listening for client (i.e. server) response
if (client)
{
if (!alreadyConnected)
{
// clear out the input buffer:
client.flush();
alreadyConnected = true;
}
while (client.connected())
{
if (client.available())
{
readString="";
while (client.available()>0)
{
//client.readStringUntil('?');
readString = client.readStringUntil('?');
client.flush();
client.stop();
}
}
}
if (readString == "err")
{
lcd.clear();
lcd.setCursor(0, 2);
lcd.print("Not found,Try again!");
Serial.println("Not found,Try again!");
delay(1500);
Number=0;
readString="";
hands = true;
DisplayResult();
}
else
{
lcd.clear();
DisplayResult();
Serial.println(readString);
hands = true;
}
} // if client
}// GetName
void DetectButtons()
{
// path = path + "DetectButtons";
//Serial.println(path);
if (Key == '*') //If cancel Button is pressed
{
Serial.println ("Button Cancel");
Number = 0;
weight = "";
readString="";
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Input Code: ");
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 2);
lcd.print(" ");
lcd.setCursor(0, 3);
lcd.print(" ");
}
if (Key == '1') //If Button 1 is pressed
{ Serial.println ("Button 1");
if (Number == 0)
Number = 1;
else
Number = (Number * 10) + 1; //Pressed twice
}
/*
if (Key == '4') //If Button 4 is pressed
{ Serial.println ("Button 4");
if (Number == 0)
Number = 4;
else
Number = (Number * 10) + 4; //Pressed twice
}
*/
if (Key == '7') //If Button 7 is pressed
{ Serial.println ("Button 7");
if (Number == 0)
Number = 7;
else
Number = (Number * 10) + 7; //Pressed twice
}
if (Key == '0')
{ Serial.println ("Button 0"); //Button 0 is Pressed
if (Number == 0)
Number = 0;
else
Number = (Number * 10) + 0; //Pressed twice
}
if (Key == '2') //Button 2 is Pressed
{ Serial.println ("Button 2");
if (Number == 0)
Number = 2;
else
Number = (Number * 10) + 2; //Pressed twice
}
if (Key == '5')
{ Serial.println ("Button 5");
if (Number == 0)
Number = 5;
else
Number = (Number * 10) + 5; //Pressed twice
}
if (Key == '8')
{ Serial.println ("Button 8");
if (Number == 0)
Number = 8;
else
Number = (Number * 10) + 8; //Pressed twice
}
if (Key == '3')
{ Serial.println ("Button 3");
if (Number == 0)
Number = 3;
else
Number = (Number * 10) + 3; //Pressed twice
}
if (Key == '6')
{ Serial.println ("Button 6");
if (Number == 0)
Number = 6;
else
Number = (Number * 10) + 6; //Pressed twice
}
if (Key == '9')
{ Serial.println ("Button 9");
if (Number == 0)
Number = 9;
else
Number = (Number * 10) + 9; //Pressed twice
}
DisplayResult();
} // end of detect buttons function
void DisplayResult()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print ("Input Code: ");
lcd.print (Number);
lcd.setCursor(0, 1);
lcd.print (readString);
lcd.setCursor(0, 2);
lcd.print ("Weight :");
lcd.print (weight);
lcd.setCursor(0, 3);
lcd.print ("*=Cncl,#=Wght,A=Save");
}
The problem is when '#' key is pressed first time with input_code =111, client.read somehow miss or skip the response (name) from server and shows blank. But when i press '#' key second time with input_code = 222, it shows previous response (name) from server.

The EthernetClient can be used to connect to remote server as in WebClient example or it is used by the EthernetServer as a peer for remote client as in ChatServer example.
If you use both, use different names. Now your client 'client' is global and clients returned from server are local but with the same name. And you can make the global client variable local too.
The variable alreadyConnected is used with local client and with server's client.
You don't stop the local client.
You have redundant while/if (client.available()) to test the request (server's client).
Why while (client.available() > 0) around readStringUntil('?')?
EthernetServer should by started with begin only once in setup().

Related

I'm trying to do an if, but to no avail

In the if (user == "A") code part {- It works, but if I put - if (user == '') <- here is invisible, but it's an asterisk {- It won't, it goes through this if, and follows the code, I'm using a matrix keyboard in arduino ... I already gave a serial.print to see, the "", responds on the keyboard but it won't.
void NovoUser() {
lcd.clear();
delay(10);
lcd.setCursor(1, 0);
lcd.print("***Novo Usuario***");
String usuario = ler(1, "Digite seu usuario:", 1, false);
bool existente = usuarioExistente(usuario);
if (usuario == "A") {
Serial.print(usuario);
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Usuario invalido");
delay(1000);
NovoUser();
} else {
if (!existente) { /*existe*/
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Usuario existente");
delay(1000);
existente = false;
return NovoUser();
} else {
lcd.clear();
String senha = ler(1, "Digite sua senha:", 4, false);
if (incluiUsuario(usuario, senha)) {
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Usuario incluido");
delay(1500);
Menu();
} else {
lcd.setCursor(0, 4);
lcd.print("erro");
delay(2000);
}
}
}
}

Arduino Ethernet W5100 device stops responding after a few days

I am running a simple web server (static IP) based on the default web server example, which is occasionally interrupted by an external input (eg. RFID reader) which sends data as a client to another server in the local network and starting the server again. the device runs as intended for a few days but then stops responding to pin inputs, accessing the server page seems to get it back on line (not sure about this) otherwise I am forced to manually reset when this happens.
Could using Serial Print(used during the debugging stage) without connecting a serial monitor be the issue?
test code:
/*
This program will decode the wiegand data from a HID RFID Reader (or, theoretically,
any other device that outputs weigand data).
The Wiegand interface has two data lines, DATA0 and DATA1. These lines are normally held
high at 5V. When a 0 is sent, DATA0 drops to 0V for a few us. When a 1 is sent, DATA1 drops
to 0V for a few us. There is usually a few ms between the pulses.
Your reader should have at least 4 connections (some readers have more). Connect the Red wire
to 5V. Connect the black to ground. Connect the green wire (DATA0) to Digital Pin 2 (INT0).
Connect the white wire (DATA1) to Digital Pin 3 (INT1). That's it!
Operation is simple - each of the data lines are connected to hardware interrupt lines. When
one drops low, an interrupt routine is called and some bits are flipped. After some time of
of not receiving any bits, the Arduino will decode the data.
*/
#include <Ethernet.h>
#include <SPI.h>
#include <EEPROM.h>
#define MAX_BITS 100 // max number of bits
#define WEIGAND_WAIT_TIME 3000 // time to wait for another weigand pulse.
unsigned char databits[MAX_BITS]; // stores all of the data bits
unsigned char bitCount; // number of bits currently captured
unsigned char flagDone; // goes low when data is currently being captured
unsigned int weigand_counter; // countdown until we assume there are no more bits
unsigned long facilityCode = 0; // decoded facility code
unsigned long cardCode = 0; // decoded card code
byte tr = 0; //testing trigger
byte ship[4]; //Home Center IP
byte wsip[4]; //Web Server IP
int scene[100]; //scene ID storage
//byte ptr = 0; //log pointer
byte ld = 0; //latest updated log
byte bc[20]; //Wiegand bitCount log
unsigned long wd[20]; //Wiegand data log
String readString1; //IP buffer
String tempstr = "{\r\n\"value\":\"";
String PostData = "{\r\n\"value\":\"1\"\r\n}"; //JSON data to send
// interrupt that happens when INTO goes low (0 bit)-2
void ISR_INT0()
{
Serial.print("0"); // uncomment this line to display raw binary
bitCount++;
flagDone = 0;
weigand_counter = WEIGAND_WAIT_TIME;
tr = 1;
}
// interrupt that happens when INT1 goes low (1 bit)
void ISR_INT1()
{
Serial.print("1"); // uncomment this line to display raw binary
if(bitCount<MAX_BITS)
databits[bitCount] = 1;
bitCount++;
flagDone = 0;
weigand_counter = WEIGAND_WAIT_TIME;
}
byte mac[] = { 0x00, 0xAB, 0xCB, 0xCD, 0xDE, 0x05 };
// byte ip[] = {192,168,4,101};
IPAddress ip(192, 168, 5, 211);
// byte gateway[] = {192,168,4,254};
// byte gateway[] = {192, 168, 5, 1};
// byte subnet[] = {255, 255, 255, 0};
// IPAddress server(192,168,4,100);
IPAddress sh(192, 168, 5, 65);
EthernetServer server(80); //server port arduino server will use
EthernetClient client;
char cnt1 = 0, cnt2 = 0;
void setup()
{
//pinMode(13, OUTPUT); // LED
pinMode(2, INPUT_PULLUP); // DATA0 (INT0)
pinMode(3, INPUT_PULLUP); // DATA1 (INT1)
Serial.begin(9600);
Serial.println("BioLite Net");
attachInterrupt(0, ISR_INT0, FALLING);
attachInterrupt(1, ISR_INT1, FALLING);
// binds the ISR functions to the falling edge of INTO and INT1
EEPROM.get(15, wsip);
IPAddress ip(wsip[0], wsip[1], wsip[2], wsip[3]);
net();
delay(10);
server.begin();
Serial.print(F("Web server is at "));
Serial.println(ip);
// Serial.print(F("server is at "));
// Serial.println(Ethernet.localIP());
EEPROM.get(10, ship);
IPAddress sh(ship[0], ship[1], ship[2], ship[3]);
Serial.print(F("Home Center is at "));
Serial.println(sh);
Serial.println(F("stored scenes are :"));
EEPROM.get(20, scene);
for (byte i = 0; i < 10 ; i++)
{
for (byte j = 0; j < 10 ; j++)
{
Serial.print((10 * i) + j);
Serial.print(" : ");
Serial.print(scene[(10 * i) + j]);
Serial.print(" ; ");
}
Serial.println();
}
EEPROM.get(310, bc);
EEPROM.get(330, wd);
EEPROM.get(305, ld);
byte temp = ld;
Serial.println(temp);
for (byte i = 0; i < 10 ; i++)
{
for (byte j = 0; j < 2 ; j++)
{
Serial.print(bc[temp]);
Serial.print(" : ");
Serial.print(wd[temp], BIN);
Serial.print(" ; ");
if (temp == 0)
temp = 20;
temp--;
}
Serial.println();
}
Serial.println();
/* temp = 19;
for (byte i = 0; i < 10 ; i++)
{
for (byte j = 0; j < 2 ; j++)
{
Serial.print(bc[temp]);
Serial.print(" : ");
Serial.print(wd[temp], BIN);
Serial.print(" ; ");
temp--;
if (temp < 0)
temp = 19;
}
Serial.println();
}*/
weigand_counter = WEIGAND_WAIT_TIME;
}
void loop()
{
// This waits to make sure that there have been no more data pulses before processing data
if (!flagDone) {
if (--weigand_counter == 0)
flagDone = 1;
}
// if we have bits and we the weigand counter went out
if (bitCount > 0 && flagDone) {
//if (tr == 1) {
tr == 0; delay(3000);
unsigned char i;
Serial.println();
if(bitCount>255) bitCount=255;
EEPROM.get(305, ld);
EEPROM.get(310, bc);
EEPROM.get(330, wd);
ld++;
if (ld > 19)
ld = 0;
Serial.println(ld);
// ptr += 5;
// ld = (ptr - 310) / 5;
bc[ld] = bitCount;
wd[ld] = 0;
for (i = 0; i < bitCount; i++)
{
Serial.print(databits[i]);
wd[ld] <<= 1;
wd[ld] |= databits[i];
}
EEPROM.put(305, ld);
EEPROM.put(310, bc);
EEPROM.put(330, wd);
Serial.println();
Serial.print("Read ");
Serial.print(bitCount);
Serial.print(" bits. ");
// we will decode the bits differently depending on how many bits we have
// see www.pagemac.com/azure/data_formats.php for mor info
if (bitCount == 35)
{
// 35 bit HID Corporate 1000 format
// facility code = bits 2 to 14
for (i = 2; i < 14; i++)
{
facilityCode <<= 1;
facilityCode |= databits[i];
}
// card code = bits 15 to 34
for (i = 14; i < 34; i++)
{
cardCode <<= 1;
cardCode |= databits[i];
}
printBits();
}
else if (bitCount == 37)
{
// HID 37 bit format H10304
// facility code = bits 2 to 17
for (i = 1; i < 17; i++)
{
facilityCode <<= 1;
facilityCode |= databits[i];
}
// card code = bits 18 to 36
for (i = 17; i < 36; i++)
{
cardCode <<= 1;
cardCode |= databits[i];
}
printBits();
}
else if (bitCount == 34)
{
// HID 34 bit format N1002
// facility code = bits 2 to 17
for (i = 1; i < 17; i++)
{
facilityCode <<= 1;
facilityCode |= databits[i];
}
// card code = bits 18 to 33
for (i = 17; i < 33; i++)
{
cardCode <<= 1;
cardCode |= databits[i];
}
printBits();
}
else if (bitCount == 26)
{
// standard 26 bit format H10301
// facility code = bits 2 to 9
for (i = 1; i < 9; i++)
{
facilityCode <<= 1;
facilityCode |= databits[i];
}
// card code = bits 10 to 25
for (i = 9; i < 25; i++)
{
cardCode <<= 1;
cardCode |= databits[i];
}
printBits();
}
else if (bitCount == 11)
{
// older Magstripe 11 bit format
// facility code = bits 6 to 9
for (i = 5; i < 9; i++)
{
facilityCode <<= 1;
facilityCode |= databits[i];
}
// card code = bits 1 to 5
for (i = 0; i < 5; i++)
{
cardCode <<= 1;
cardCode |= databits[i];
}
printBits();
}
else {
// you can add other formats if you want!
Serial.println("Unable to decode.");
}
EEPROM.get(10, ship);
IPAddress sh(ship[0], ship[1], ship[2], ship[3]);
EEPROM.get(20, scene);
String tempstr = "{\r\n\"value\":\"";
String PostData = "{\r\n\"value\":\"1\",\"invokeScenes\":true\r\n}"; //JSON data to send
tempstr = tempstr + cardCode;
PostData = tempstr + "\",\"invokeScenes\":true\r\n}";
if (client.connect(sh, 80)) {
client.print("GET /api/sceneControl?id=");
client.print(scene[cardCode]);
client.println("&action=start HTTP/1.1");
auth(sh);
Serial.print("Scene ");
Serial.print(scene[cardCode]);
Serial.println(" treggered");
/* }
if (Ethernet.begin(mac) == 0) {
Serial.println(F("Failed to configure Ethernet using DHCP"));
delay(3000);
Ethernet.begin(mac, ip);
if (Ethernet.localIP() != ip)
{
Serial.println(F("Failed to configure Ethernet using static IP"));
for (;;)
;
}
}
if (!client.connected())client.stop();
delay(1);
if (client.connect(sh, 80)) {*/
client.println("PUT /api/globalVariables/UID HTTP/1.1");
auth(sh);
Serial.print(cardCode);
Serial.println(" registered");
}
//if (!client.connected())client.stop();
while (client.available()) {
char c = client.read();
Serial.print(c);
}
// if the server's disconnected, stop the client:
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
// do nothing forevermore:
//while (true);
}
// cleanup and get ready for the next card
bitCount = 0;
facilityCode = 0;
cardCode = 0;
for (i = 0; i < MAX_BITS; i++)
{
databits[i] = 0;
}
delay(10);
net();
delay(10);
server.begin();
}
// Create a client connection
EthernetClient nclient = server.available();
if (nclient) {
Serial.println(F("new client"));
while (nclient.connected()) {
if (nclient.available()) {
/* char c = client.read();
Serial.write(c);
//read char by char HTTP request
if (readString1.length() < 100) {
//store characters to string
readString1 += c;
}*/
readString1 = nclient.readStringUntil('\n');
Serial.println(readString1);
//if HTTP request has ended– 0x0D is Carriage Return \n ASCII
// if (c == 0x0D) {
nclient.println("HTTP/1.1 200 OK"); //send new page
nclient.println("Content-Type: text/html");
nclient.println();
nclient.println(F("<HTML>"));
nclient.println(F("<HEAD>"));
nclient.println(F("<TITLE> Wegand to Home Center Configurator</TITLE>"));
nclient.println(F("</HEAD>"));
nclient.println(F("<BODY style=\"background-color:#F0F0FF; text-align: center;\">"));
nclient.println(F("<br>"));
nclient.println(F("<H1 style=\"color:LimeGreen;\">Wegand<span style=\"color:Teal;\">2</span><span style=\"color:Blue;\">HC</span></H1>"));
// client.println(F("<hr>"));
nclient.println(F("<br>"));
//nclient.println(F("<a style=\"color:SteelBlue;background-color:White;padding: 5px;\" href=\"/?TEST\"\">TEST</a><br /><br />"));
nclient.println(F("<form id=\"txt_form\" name=\"frmText\">"));
nclient.println(F("<H2 style=\"color:Crimson;\"><b>Configurator</b></H2>"));
nclient.println(F("<label style=\"color:DodgerBlue;\" for=\"code\">code : <input type=\"password\" id=\"code\" size=\"4\" maxlength=\"4\" value=\"0000\" /></label><br /><br />"));
nclient.println(F("<label style=\"color:DodgerBlue;\" for=\"hcip\">Home Center IP : <input type=\"text\" id=\"hcip\" size=\"15\" minlength=\"15\" maxlength=\"15\" value=\""));
if (ship[0] < 10)
{
nclient.print("00");
}
else if (ship[0] < 100)
{
nclient.print("0");
}
nclient.print(ship[0]);
nclient.print(F("."));
if (ship[1] < 10)
{
nclient.print("00");
}
else if (ship[1] < 100)
{
nclient.print("0");
}
nclient.print(ship[1]);
nclient.print(F("."));
if (ship[2] < 10)
{
nclient.print("00");
}
else if (ship[2] < 100)
{
nclient.print("0");
}
nclient.print(ship[2]);
nclient.print(F("."));
if (ship[3] < 10)
{
nclient.print("00");
}
else if (ship[3] < 100)
{
nclient.print("0");
}
nclient.print(ship[3]);
nclient.println(F("\" required></label><br /><br />"));
nclient.println(F("<label style=\"color:DodgerBlue;\" for=\"sip\">Web Server IP : <input type=\"text\" id=\"sip\" size=\"15\" minlength=\"15\" maxlength=\"15\" value=\""));
if (wsip[0] < 10)
{
nclient.print("00");
}
else if (wsip[0] < 100)
{
nclient.print("0");
}
nclient.print(wsip[0]);
nclient.print(F("."));
if (wsip[1] < 10)
{
nclient.print("00");
}
else if (wsip[1] < 100)
{
nclient.print("0");
}
nclient.print(wsip[1]);
nclient.print(F("."));
if (wsip[2] < 10)
{
nclient.print("00");
}
else if (wsip[2] < 100)
{
nclient.print("0");
}
nclient.print(wsip[2]);
nclient.print(F("."));
if (wsip[3] < 10)
{
nclient.print("00");
}
else if (wsip[3] < 100)
{
nclient.print("0");
}
nclient.print(wsip[3]);
nclient.println(F("\" readonly></label><br /><br />"));
nclient.println(F("<label style=\"color:DodgerBlue;\" for=\"uid\">User ID : <input type=\"text\" id=\"uid\" size=\"2\" maxlength=\"2\" autocomplete=\"on\" value=\"00\" /></label><br /><br />"));
nclient.println(F("<label style=\"color:DodgerBlue;\" for=\"sid\">Scene ID : <input type=\"text\" id=\"sid\" size=\"4\" maxlength=\"4\" autocomplete=\"on\" value=\"0000\" /></label><br /><br />"));
nclient.println(F("<a style=\"color:SteelBlue;background-color:White;padding: 5px;\" href=\"\" onclick=\"this.href='/?'+document.getElementById('code').value+document.getElementById('uid').value+document.getElementById('sid').value+document.getElementById('hcip').value+document.getElementById('sip').value\" >EDIT</a>"));
nclient.println(F("</form>"));
nclient.println(F("</BODY>"));
nclient.println(F("</HTML>"));
delay(10);
//stopping client
nclient.stop();
Serial.println(F("client disconnected"));
if (readString1.indexOf("?1729") == 5 && readString1.indexOf("HTTP/1.1") == 47) //checks code
{
Serial.println(F("pwd match"));
// readString1.toCharArray(url, 25);
Serial.println(readString1);
byte ad = readString1.substring(10, 12).toInt();
Serial.println(ad);
if (ad > 0 && ad < 100) {
scene[ad] = readString1.substring(12, 16).toInt();
Serial.println(scene[ad]);
}
else
Serial.println(F("invalid UID"));
byte p = 16;
for (byte i = 0; i < 4; i++) {
ship[i] = readString1.substring(p, p + 3).toInt();
p = p + 4;
}
p--;
for (byte i = 0; i < 4; i++) {
wsip[i] = readString1.substring(p, p + 3).toInt();
p = p + 4;
}
EEPROM.put(10, ship);
EEPROM.put(15, wsip);
EEPROM.put(20, scene);
delay(1500);
EEPROM.get(10, ship);
EEPROM.get(15, wsip);
EEPROM.get(20, scene);
//digitalWrite(5, HIGH);
//delay(1500);
//digitalWrite(5, LOW);
Serial.println(F("Edited"));
}
//clearing string for next read
readString1 = "";
// }
}
}
}
switch (Ethernet.maintain())
{
case 1:
//renewed fail
Serial.println(F("Error: renewed fail"));
break;
case 2:
//renewed success
Serial.println(F("Renewed success"));
//print your local IP address:
Serial.print(F("server is at "));
Serial.println(Ethernet.localIP());
break;
case 3:
//rebind fail
Serial.println(F("Error: rebind fail"));
break;
case 4:
//rebind success
Serial.println(F("Rebind success"));
//print your local IP address:
Serial.print(F("server is at "));
Serial.println(Ethernet.localIP());
break;
default:
//nothing happened
break;
}
}
void printBits()
{
// I really hope you can figure out what this function does
Serial.println();
Serial.print("FC = ");
Serial.print(facilityCode);
Serial.print(", CC = ");
Serial.println(cardCode);
}
void net()
{
if (Ethernet.begin(mac) == 0) {
Serial.println(F("Failed to configure Ethernet using DHCP"));
// if (Ethernet.hardwareStatus() == EthernetNoHardware) {
// Serial.println(F("Ethernet shield was not found. Sorry, can't run without hardware. :("));
// } else if (Ethernet.linkStatus() == LinkOFF) {
// Serial.println(F("Ethernet cable is not connected."));
// } else {
// Serial.println(F("No idea why"));
// }
delay(3000);
Ethernet.begin(mac, ip);
if (Ethernet.localIP() != ip)
{
Serial.println(F("Failed to configure Ethernet using static IP"));
for (;;)
;
}
}
Serial.print(F("server is at "));
Serial.println(Ethernet.localIP());
ip = Ethernet.localIP();
for (byte i = 0; i < 4; i++) {
wsip[i] = ip[i];
}
EEPROM.put(15, wsip);
}
void auth(IPAddress sh)
{
Serial.println(sh);
client.print("Host: ");
client.println(sh);
client.println("Authorization: Basic YmVuc2U6Qmlnc"); //need to insert base 64 user:password
client.print("Content-Length: ");
client.println(PostData.length());
client.println();
client.println(PostData);
}

How to accept input from user after alarm is triggered

So as of right now when I arm the system and move my hand in front of the PIR sensor it says system triggered how do i get it to take a password from the user to deactivate the system. Also when the system is deactive it should say on the screen "Not Active"
#include <LiquidCrystal.h>
#include <Password.h>
#include <Keypad.h>
//Password
Password password = Password("1234");
LiquidCrystal lcd(0, 1, 10, 11, 12, 13);
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = { // Define the Keymap
{
'1','2','3','A' }
,
{
'4','5','6','B' }
,
{
'7','8','9','C' }
,
{
'*','0','#','D' }
};
byte rowPins[ROWS] = {9,8,7,6};
byte colPins[COLS] = {5,4,3,2};
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS);
int armed = 0;
const int pir1 = A4;
int sensorHit = 0;
int alarmStatus = 0;
int alarmActive = 0;
int zone = 0;
void setup() {
// put your setup code here, to run once:
lcd.begin(16,2);
pinMode(pir1, INPUT);
mainScreen();
keypad.addEventListener(keypadEvent);
}
void loop() {
// put your main code here, to run repeatedly:
keypad.getKey();
if(alarmActive == 1){
if(digitalRead(pir1) == HIGH){
zone = 0;
alarmTriggered();
}
}
}
void keypadEvent(KeypadEvent eKey){
switch (keypad.getState()){
case PRESSED:
lcd.print(eKey);
switch (eKey){
case '#': checkPassword(); break;
default:
password.append(eKey);
}
}
}
void alarmTriggered(){
password.reset();
alarmStatus = 1;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("SYSTEM TRIGGERED");
lcd.print(0,1);
if(zone == 0){
lcd.print(" FRONT DOOR OPEN ");
}
}
void checkPassword(){
if (password.evaluate()){ //if code is correct:
lcd.clear(); //clear LCD
lcd.print("VALID PASSWORD"); //print message
password.reset(); //resets password after correct entry
delay(1500); //wait...
lcd.clear(); //clear
if (alarmStatus==0 && alarmActive == 0){ //if system is off (ie: disarmed)
lcd.print("ARMED!"); //display message
alarmActive=1; //system armed
alarmStatus=1;
delay(2000); //wait
lcd.clear(); //clear
lcd.setCursor(0, 0); //return to top left of LCD
lcd.print("Code to disarm:"); //back to where we began
}
else{
lcd.print("DISARMED!"); //display message
alarmActive=0; //system unarmed
alarmStatus=0;
delay(2000); //wait
lcd.clear(); //clear
lcd.setCursor(0, 0); //return to top left of LCD
lcd.print("Code to arm:"); //back to where we began
}
}
else{ //if password is incorrect:
lcd.clear();
lcd.print("INVALID PASSWORD");
password.reset(); //resets password after INCORRECT entry
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Retry Code:");
}
}
void mainScreen(){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Enter Pin:");
}
You need an input device for entering the password. A simple example can be 10 switches where each switch represent 1 so our password has to be between 0 to 10. You add the switches values together and compare with your set password. The rest should be easy for you.

MQTT slow to subscribe and debounce problems

I'm after some desperately needed help please.
My setup consists of two arduinos (EtherTens) and a Raspberry Pi (running Mosquitto MQTT broker and Home Assistant). On one Arduino I have a security sensor shield with two PIRs attached and publishing states to the broker (this works 100% how it should).
On my other arduino, I have a couple of relay 8 driver shields (they use I2C) connected to two 8 channel relay boards (total of 16 relays connected).
I have toggle switches connected to switch a few lights in the house for hardware activation plus I have it setup to be activated through Home Assistant with MQTT topics.
The issues I've come across is random relay activation from turning other lights on in the house. I think there's some line interference somewhere and am hoping that a software debounce might solve the issue but I am lost in the code (I already have 10k pulldown resistors on my toggle switch setup).
The other issue is the the Arduino running the relay shields is really (and I mean really) slow to subscribe to the broker...I'm talking anywhere up to 10 seconds at times.
Would anyone be able to suggest the best way to fix my code please?
// This subscribes to MQTT IOT get the PIR sensor states //
#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
#include <Wire.h>
#define SHIELD_1_I2C_ADDRESS 0x20 // 0x20 is the address with all jumpers removed
#define SHIELD_2_I2C_ADDRESS 0x21 // 0x21 is the address with a jumper on position A0
#define MAC_I2C_ADDRESS 0x50 // Microchip 24AA125E48 I2C ROM address
// Update these with values suitable for your network.
byte mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress ip(192, 168, 2, 110);
IPAddress server(192, 168, 2, 149);
byte shield1BankA = 0; // Current status of all outputs on first shield, one bit per output
byte shield2BankA = 0; // Current status of all outputs on second shield, one bit per output
const int buttonPin2 = 2;
const int buttonPin3 = 3;
const int buttonPin4 = 4;
const int buttonPin5 = 5;
const int buttonPin6 = 6;
int buttonState2;
int buttonState3;
int buttonState4;
int buttonState5;
int buttonState6;
int lastButtonState2 = LOW;
int lastButtonState3 = LOW;
int lastButtonState4 = LOW;
int lastButtonState5 = LOW;
int lastButtonState6 = LOW;
unsigned long lastDebounceTime2 = 0;
unsigned long lastDebounceTime3 = 0;
unsigned long lastDebounceTime4 = 0;
unsigned long lastDebounceTime5 = 0;
unsigned long lastDebounceTime6 = 0;
unsigned long debounceDelay2 = 50;
unsigned long debounceDelay3 = 50;
unsigned long debounceDelay4 = 50;
unsigned long debounceDelay5 = 50;
unsigned long debounceDelay6 = 50;
EthernetClient ethClient;
PubSubClient client(server, 1883, callback, ethClient);
void callback(char* topic, byte* payload, unsigned int length) {
// handle message arrived
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
// Switch on the Hallway Light
if (strcmp(topic, "left/hallwaylight") == 0) {
if ((char)payload[0] == '1')
{
setLatchChannelOn(1);
client.publish("left/hallwaylight/state", "1");
delay(500);
}
else if ((char)payload[0] == '0') //Controlled from Home Assistant
{
setLatchChannelOff(1);
delay(500);
client.publish("left/hallwaylight/state", "0");
}
}
// Switch on the Workshop Light - Sensor 2
if (strcmp(topic, "left/workshoplight") == 0) {
if ((char)payload[0] == '1')
{
setLatchChannelOn(2);
client.publish("left/workshoplight/state", "1");
delay(500);
}
else if ((char)payload[0] == '0') //Controlled from Home Assistant
{
setLatchChannelOff(2);
delay(500);
client.publish("left/workshoplight/state", "0");
}
}
/*
// Switch on the #############
if (strcmp(topic, "left/sensor2") == 0) {
if ((char)payload[0] == '1')
{
setLatchChannelOn(2);
client.publish("left/workshoplight/state", "1");
Serial.println("Workshop Light On");
delay(500);
}
else if ((char)payload[0] == '0') //Controlled from Home Assistant
{
setLatchChannelOff(2);
delay(500);
client.publish("left/workshoplight/*&^*&^&*", "0");
}
}
// Switch on the ####################
if (strcmp(topic, "left/sensor2") == 0) {
if ((char)payload[0] == '1')
{
setLatchChannelOn(2);
client.publish("left/workshoplight/state", "1");
Serial.println("Workshop Light On");
delay(500);
}
else if ((char)payload[0] == '0') //Controlled from Home Assistant
{
setLatchChannelOff(2);
delay(500);
client.publish("left/workshoplight/khebfjseghf", "0");
}
} */
// Switch on the Fountain
if (strcmp(topic, "left/fountain") == 0) {
if ((char)payload[0] == '1')
{
setLatchChannelOn(8);
client.publish("left/fountain/state", "1");
delay(500);
}
else if ((char)payload[0] == '0') //Controlled from Home Assistant
{
setLatchChannelOff(8);
delay(500);
client.publish("left/fountain/state", "0");
}
}
// Switch on the Entrance Lights
if (strcmp(topic, "left/entrancelights") == 0) {
if ((char)payload[0] == '1')
{
setLatchChannelOn(7);
client.publish("left/entrancelights/state", "1");
delay(500);
}
else if ((char)payload[0] == '0') //Controlled from Home Assistant
{
setLatchChannelOff(7);
delay(500);
client.publish("left/entrancelights/state", "0");
}
}
// Switch on the Foyer Lights
if (strcmp(topic, "left/foyerlights") == 0) {
if ((char)payload[0] == '1')
{
setLatchChannelOn(6);
client.publish("left/foyerlights/state", "1");
delay(500);
}
else if ((char)payload[0] == '0') //Controlled from Home Assistant
{
setLatchChannelOff(6);
delay(500);
client.publish("left/foyerlights/state", "0");
}
}
// Switch on the Driveway Lights - Sensor 1
if (strcmp(topic, "left/drivewaylights") == 0) {
if ((char)payload[0] == '1')
{
setLatchChannelOn(9);
client.publish("left/drivewaylights/state", "1");
delay(500);
}
else if ((char)payload[0] == '0') //Controlled from Home Assistant
{
setLatchChannelOff(9);
delay(500);
client.publish("left/drivewaylights/state", "0");
}
}
// Switch on the Spa Light
if (strcmp(topic, "left/spalight") == 0) {
if ((char)payload[0] == '1')
{
setLatchChannelOn(10);
client.publish("left/spalight/state", "1");
delay(500);
}
else if ((char)payload[0] == '0') //Controlled from Home Assistant
{
setLatchChannelOff(10);
delay(500);
client.publish("left/spalight/state", "0");
}
}
// Switch on the Pool Light
if (strcmp(topic, "left/poollight") == 0) {
if ((char)payload[0] == '1')
{
setLatchChannelOn(11);
client.publish("left/poollight/state", "1");
delay(500);
}
else if ((char)payload[0] == '0') //Controlled from Home Assistant
{
setLatchChannelOff(11);
delay(500);
client.publish("left/poollight/state", "0");
}
}
// Switch on the Tree Light
if (strcmp(topic, "left/treelight") == 0) {
if ((char)payload[0] == '1')
{
setLatchChannelOn(12);
client.publish("left/treelight/state", "1");
delay(500);
}
else if ((char)payload[0] == '0') //Controlled from Home Assistant
{
setLatchChannelOff(12);
delay(500);
client.publish("left/treelight/state", "0");
}
}
// Switch on the Fountains
if (strcmp(topic, "left/fountains") == 0) {
if ((char)payload[0] == '1')
{
setLatchChannelOn(13);
client.publish("left/fountains/state", "1");
delay(500);
}
else if ((char)payload[0] == '0') //Controlled from Home Assistant
{
setLatchChannelOff(13);
delay(500);
client.publish("left/fountains/state", "0");
}
}
// Switch on the Spa
if (strcmp(topic, "left/spa") == 0) {
if ((char)payload[0] == '1')
{
setLatchChannelOn(16);
client.publish("left/spa/state", "1");
delay(500);
}
else if ((char)payload[0] == '0') //Controlled from Home Assistant
{
setLatchChannelOff(16);
delay(500);
client.publish("left/spa/state", "0");
}
}
}
void setup()
{
Wire.begin(); // Wake up I2C bus
Serial.begin(38400);
Ethernet.begin(mac, ip);
// Note - the default maximum packet size is 128 bytes. If the
// combined length of clientId, username and password exceed this,
// you will need to increase the value of MQTT_MAX_PACKET_SIZE in
// PubSubClient.h
/* Set up the Relay8 shields */
initialiseShield(SHIELD_1_I2C_ADDRESS);
sendRawValueToLatch1(0); // If we don't do this, channel 6 turns on! I don't know why
initialiseShield(SHIELD_2_I2C_ADDRESS);
sendRawValueToLatch2(0); // If we don't do this, channel 6 turns on! I don't know why
pinMode(buttonPin2, INPUT);
pinMode(buttonPin3, INPUT);
pinMode(buttonPin4, INPUT);
pinMode(buttonPin5, INPUT);
pinMode(buttonPin6, INPUT);
}
void loop()
{
if (!client.connected()) {
reconnect();
}
int reading2 = digitalRead(buttonPin2);
int reading3 = digitalRead(buttonPin3);
int reading4 = digitalRead(buttonPin4);
int reading5 = digitalRead(buttonPin5);
int reading6 = digitalRead(buttonPin6);
if (reading2 != lastButtonState2) {
lastDebounceTime2 = millis();
}
if ((millis() - lastDebounceTime2) > debounceDelay2) {
if (reading2 != buttonState2) {
buttonState2 = reading2;
if ((buttonPin2 == HIGH) && What to put here????) {
toggleLatchChannel(1);
client.publish("left/hallwaylight/state", "1");
}
/*if (digitalRead(2) == HIGH) //Digital pin for Hall Light
{
toggleLatchChannel(1);
delay(1000);
}*/
}
}
lastButtonState2 = reading2;
if (digitalRead(3) == HIGH) //Digital pin for Fountain
{
toggleLatchChannel(6);
delay(1000);
}
if (digitalRead(4) == HIGH) //Digital pin for Entrance Lights
{
toggleLatchChannel(7);
delay(1000);
}
if (digitalRead(5) == HIGH) //Digital pin for Foyer Lights
{
toggleLatchChannel(8);
delay(1000);
}
if (digitalRead(6) == HIGH) //Digital pin for Driveway Lights - to be removed
{
toggleLatchChannel(9);
delay(1000);
}
client.loop();
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("leftArduinoClient")) {
Serial.println("connected");
client.subscribe("left/#");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void initialiseShield(int shieldAddress)
{
// Set addressing style
Wire.beginTransmission(shieldAddress);
Wire.write(0x12);
Wire.write(0x20); // use table 1.4 addressing
Wire.endTransmission();
// Set I/O bank A to outputs
Wire.beginTransmission(shieldAddress);
Wire.write(0x00); // IODIRA register
Wire.write(0x00); // Set all of bank A to outputs
Wire.endTransmission();
}
void toggleLatchChannel(byte channelId)
{
if ( channelId >= 1 && channelId <= 8 )
{
byte shieldOutput = channelId;
byte channelMask = 1 << (shieldOutput - 1);
shield1BankA = shield1BankA ^ channelMask;
sendRawValueToLatch1(shield1BankA);
}
else if ( channelId >= 9 && channelId <= 16 )
{
byte shieldOutput = channelId - 8;
byte channelMask = 1 << (shieldOutput - 1);
shield2BankA = shield2BankA ^ channelMask;
sendRawValueToLatch2(shield2BankA);
}
}
void setLatchChannelOn (byte channelId)
{
if ( channelId >= 1 && channelId <= 8 )
{
byte shieldOutput = channelId;
byte channelMask = 1 << (shieldOutput - 1);
shield1BankA = shield1BankA | channelMask;
sendRawValueToLatch1(shield1BankA);
}
else if ( channelId >= 9 && channelId <= 16 )
{
byte shieldOutput = channelId - 8;
byte channelMask = 1 << (shieldOutput - 1);
shield2BankA = shield2BankA | channelMask;
sendRawValueToLatch2(shield2BankA);
}
}
void setLatchChannelOff (byte channelId)
{
if ( channelId >= 1 && channelId <= 8 )
{
byte shieldOutput = channelId;
byte channelMask = 255 - ( 1 << (shieldOutput - 1));
shield1BankA = shield1BankA & channelMask;
sendRawValueToLatch1(shield1BankA);
}
else if ( channelId >= 9 && channelId <= 16 )
{
byte shieldOutput = channelId - 8;
byte channelMask = 255 - ( 1 << (shieldOutput - 1));
shield2BankA = shield2BankA & channelMask;
sendRawValueToLatch2(shield2BankA);
}
}
void sendRawValueToLatch1(byte rawValue)
{
Wire.beginTransmission(SHIELD_1_I2C_ADDRESS);
Wire.write(0x12); // Select GPIOA
Wire.write(rawValue); // Send value to bank A
shield1BankA = rawValue;
Wire.endTransmission();
}
void sendRawValueToLatch2(byte rawValue)
{
Wire.beginTransmission(SHIELD_2_I2C_ADDRESS);
Wire.write(0x12); // Select GPIOA
Wire.write(rawValue); // Send value to bank A
shield2BankA = rawValue;
Wire.endTransmission();
}
/** Required to read the MAC address ROM */
byte readRegister(byte r)
{
unsigned char v;
Wire.beginTransmission(MAC_I2C_ADDRESS);
Wire.write(r); // Register to read
Wire.endTransmission();
Wire.requestFrom(MAC_I2C_ADDRESS, 1); // Read a byte
while (!Wire.available())
{
// Wait
}
v = Wire.read();
return v;
}
Subscribing to the broker may take long because of the delay in this function:
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("leftArduinoClient")) {
Serial.println("connected");
client.subscribe("left/#");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
If you fail to connect on the first attempt, the program will wait for 5 seconds. Have you checked with serial monitor if this is the case? You should see two "failed..." messages.
As for relays: debouncing is only for hardware switches - when you press a button there is a short period when electrcal contacts in it bounce back and forth connecting and disconnecting several times. When you connect a switch to a microcontroller, it will read several transitions of digital pin connected to a button. Debouncing is a way to ignore these short pulses.
That being said, there is no need to debounce a signal that comes from another microcontroller, or a PC - there are no mechanical parts that can oscillate generating "fake" pulses. Try to write a short test program that will just activate all relays in a sequence, one at a time, without reading any external inputs. That way you will know, if the problem comes from a bug in your code, or is it a hardware problem.

Arduino Serial Returning unknown value

So right now that is my code, It is trying to read the different RGB Values for my LED Strip
However, When I get to where I ask for the green value, there is an unknown byte going through and it automatically goes straight to the else part in green();
I didn't input anything yet but Serial says there is something there. What is it?
#define REDPIN 5
#define GREENPIN 6
#define BLUEPIN 3
#define FADESPEED 5 // make this higher to slow down
void setup() {
pinMode(REDPIN, OUTPUT);
pinMode(GREENPIN, OUTPUT);
pinMode(BLUEPIN, OUTPUT);
Serial.begin(9600);
Serial.println("Starting Program....");
start();
}
int g = 0;
char val = 0;
String valstr = "";
void loop(){
if(Serial.available() > 0){
val = Serial.read();
if(val != '\n'){
valstr += val;
}
else{
Serial.println(valstr);
if (valstr != "Yes"){
valstr = "";
start();
}
else{
Serial.print("Now Asking for RGB values: \n");
Serial.println("What is green value: ");
green();
//
//
valstr = "";
// start();
}
valstr = "";
// green();
}
}
}
void start(){
Serial.print("Do you want a new color? Enter Yes/No: ");
}
char gbyte = 0;
String gstr = "";
boolean not_number;
int gnum = 256;
void green(){
if(Serial.available() > 0)
gbyte = Serial.read();
if ((gbyte >= '0') && (gbyte <= '9')) {
gstr += gbyte;
}
else if(gbyte == ' '){
Serial.println("This is not a number! \n");
Serial.println("Enter a valid number!");
gstr = "";
gbyte = Serial.read();
}
else{
Serial.println(gstr);
Serial.println("This is a number");
}
gstr += gbyte;
// gnum = gstr.toInt();
// if((gnum >= 0) && (gnum <= 255))
I think the issue is with the parsing of the integer from the serial port. Arduino has a built-in function for this :
https://www.arduino.cc/en/Reference/ParseInt

Resources