I have an Arduino UNO R3 that reads a specific value from my Web Page.
I have an LED attached to the PIN 13 & GND of my Arduino.
When the Arduino reads 1 from my Web Page, it should turn the LED ON. When it reads 0, it should turn it off.
Following is the code for that:
#include "SIM900.h"
#include <SoftwareSerial.h>
#include "inetGSM.h"
InetGSM inet;
#define ledPin 13
char msg[165];
char store[2];
char a;
char b;
char* disp;
boolean started=false;
void setup()
{
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
//Serial connection.
Serial.begin(9600);
Serial.println("GSM Shield testing.");
//Start configuration of shield with baudrate.
//For http uses is raccomanded to use 4800 or slower.
if (gsm.begin(2400)) {
Serial.println("\nstatus=READY");
started=true;
} else Serial.println("\nstatus=IDLE");
if(started)
{
//GPRS attach, put in order APN, username and password.
//If no needed auth let them blank.
if (inet.attachGPRS("TATA.DOCOMO.INTERNET", "", ""))
Serial.println("status=ATTACHED");
else Serial.println("status=ERROR");
delay(1000);
//TCP Client GET, send a GET request to the server and
//save the reply.
//Print the results.
}
}
void loop()
{
inet.httpGET("www.boat.esy.es", 80, "/retrieve.php", msg, 165);
disp = strstr(msg,"\r\n\r\n");
disp = disp+4;
a = disp[0];
b = disp[1];
Serial.println(b);
if(b=='1')
{
digitalWrite(ledPin, HIGH);
}
if(b=='0');
{
digitalWrite(ledPin, LOW);
}
}
Problem here is, when I disable the digitalWrite(ledPin,LOW), that is when I comment it out, the LED turns on & stays that way.
But the moment I enable it & load the code on my Arduino, it won't even turn on.
I'm wondering if it's a logical error or something else. Because the turning on & off of the LED depends completely on the conditions being satisfied. And for now, my Web Page returns only 1, hence the LED should stay on. But when I include both digitalWrite(ledPin, HIGH) and digitalWrite(ledPin, LOW) in the same code and run it, it doesn't work. I can see the Serial printing out the messages associated with the LED ON, but I don't see the LED turning ON.
Thank You for your time!!
First of all you have a semicolon that I think should not be in your second if-statement?
if(b=='0'); <--
{
digitalWrite(ledPin, LOW);
}
Start by trying to remove that and see if there is a difference.
Related
I'm currently working on a lasertag game with several weapons.
I would like to use one arduino nano in each weapon. It should be able to receive the IR-signals of the opponents as well as send IR-signals if a button is triggered.
So now there comes my problem:
I implemented an interrupt for the IR-receiver pin, so that an opponent's shot is always detected even when I'm shooting.
When the button is permanently pressed, the IR LED will shoot every 300 milliseconds (the send-function takes approximately 70ms and I implemented a delay of 230ms).
Unfortunately, the Nano won't detect any signal of the receiver in those 300ms.
However, if I disconnect the IR-LED everything seems to work perfectly.
Now I'm wondering, why the IR-LEDs connection has an effect on the functionality of my code.
Do you know any way I could solve this problem?
Here you can see the entire code I implemented:
#define IR_SEND_PIN 3
#define BUTTON_PIN 10
#define LED_PIN 12
#include <IRremote.hpp>
#include <Arduino.h>
uint8_t sAddress = 0;
uint8_t sCommand = 0x59;
uint8_t sRepeats = 0;
volatile uint8_t hitData;
void setup() {
IrSender.begin();
IrReceiver.begin(IR_RECEIVE_PIN);
pinMode(LED_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(IR_RECEIVE_PIN), HIT, CHANGE);
}
void HIT() {
if (IrReceiver.decode()) {
hitData = IrReceiver.decodedIRData.command;
}
IrReceiver.resume();
}
void loop() {
if (digitalRead(BUTTON_PIN) == LOW) {
IrSender.sendNEC(sAddress, sCommand, sRepeats);
delay(120);
}
if (hitData == sCommand) { // indicates received signal 0x59
hitData = 0x00;
IrReceiver.resume();
digitalWrite(LED_PIN, HIGH);
delay(8);
digitalWrite(LED_PIN, LOW);
}
}```
Good afternoon, I want to make a continuously operable gateway that measures temperature with esp32.
The device sends data via MQTT every 1.5 seconds.
Esp freezes after 12 - 24 hours.
I read that some users operate the device every 6-7 months without resetting, how can I operate the device for a long time without resetting it?
Note1: As a workaround in the code I reset the device with MQTT, Ethernet and ESP.restart () every 12 hours before it can freeze.
Note2: LEDs indicate that the system is working.
Red lights when ethernet or MQTT cannot be connected.
Blue indicates trying to connect to MQTT or ethernet.
Green indicates that the system is active. When the device was frozen, the green led was still on.
Versions of libraries I use:
Arduino IDE == 1.8.14
ESP Library Version == 1.0.6
MQTT Library Version == 2.5.0
ESP Library Version == 2.0.9
ESP Link: https://www.direnc.net/esp32-wroom-32u-wifi-bluetooth-gelistirme-modulu-en
The code:
#include <UIPEthernet.h>
#include <ArduinoJson.h>
#include <MQTT.h>
#include <DHT.h>
//////////////////////// ETHERNET CONFİG //////////////////////////
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
//////////////////////// ETHERNET CONFİG //////////////////////////
//////////////////////// LED & DHT22 CONFİG //////////////////////////
byte red = 2;
byte green = 0;
byte blue = 4;
byte temp = 15;
#define DHTTYPE DHT22
DHT dht = DHT(temp, DHTTYPE);
//////////////////////// LED & DHT22 CONFİG //////////////////////////
//////////////////////// MQTT CONFİG //////////////////////////
#define mqttServer IPAddress(xxx,xxx,xx,xxx)
const char* mqttUser = "test";
const char* mqttPassword = "test";
const char* deviceId = "Ai-Sens 1";
//////////////////////// MQTT CONFİG //////////////////////////
unsigned long lastMillis = 0;
byte x;
byte y;
EthernetClient net;
MQTTClient client;
//Receives an external reset command every 12 hours
void callback(String &topic, String &payload) {
if (payload == "1")
{
ESP.restart(); // This is just a workaround to avoid the freezing issue
}
}
void setup_eth() {
delay(10);
digitalWrite(blue, HIGH); // turn the LED on
//Serial.print("connecting ethernet...");
if (Ethernet.begin(mac) == 0) {
// Serial.println("Failed to configure Ethernet using DHCP");
for (;;)
;
}
Ethernet.begin(mac, Ethernet.localIP());
digitalWrite(blue, LOW);
}
void connect() {
//Serial.print("connecting mqtt...");
digitalWrite(blue, HIGH);
while (!client.connected()) {
if (client.connect(deviceId, mqttUser, mqttPassword)) {
// Subscribe
//client.subscribe("esp/data1");
} else {
delay(500);
}
}
//Serial.println("\nconnected!");
digitalWrite(blue, LOW);
//client.subscribe("esp/data1");
}
void setup() {
//Serial.begin(115200);
pinMode(red, OUTPUT);
pinMode(green, OUTPUT);
pinMode(blue, OUTPUT);
digitalWrite(red, LOW);
digitalWrite(green, LOW);
digitalWrite(blue, LOW);
dht.begin();
setup_eth();
client.setHost(mqttServer, 1883);
client.setKeepAlive(90);
client.begin(mqttServer, net);
connect();
}
void loop() {
client.loop();
delay(10);
client.subscribe("esp/rst");
client.onMessage(callback);
StaticJsonBuffer<300> JSON;
JsonObject& JSONencoder = JSON.createObject();
if (millis() - lastMillis > 1500) {
digitalWrite(green, LOW);
digitalWrite(blue, LOW);
digitalWrite(red, LOW);
if (!client.connected()) {
digitalWrite(red, HIGH);
if (y == 5) {
//Serial.println("Reboot System Now....");
ESP.restart();
y = 0;
}
y++;
connect();
}
if (Ethernet.linkStatus() == LinkON) {
// Serial.println("On");
digitalWrite(green, HIGH);
}
else {
digitalWrite(red, HIGH);
if (x == 5) {
//Serial.println("Reboot System Now....");
ESP.restart();
x = 0;
}
x++;
}
lastMillis = millis();
//Serial.println(Ethernet.maintain ());
JSONencoder["DEVICE = "] = deviceId;
JSONencoder["USER = "] = mqttUser;
JSONencoder["TEMP = "] = dht.readTemperature();
JSONencoder["HUMD = "] = dht.readHumidity();
JSONencoder["STATE = "] = true;
char JSONmessageBuffer[100];
JSONencoder.printTo(JSONmessageBuffer, sizeof(JSONmessageBuffer));
client.publish("esp/data1", JSONmessageBuffer);
}
}
It would be helpful to have the output of device from the moment it reboots - this might describe what caused it.
Without that, the best guess is that you're depleting the RAM. To check for this, you should periodically print out the available heap space (the FreeRTOS function to do it is xPortGetFreeHeapSize()).
I notice that with each iteration of loop() you do things which should be done only once - the calls to subscribe() and onMessage() are very likely not needed every time you want to publish data, and they likely allocate new heap memory to store the relevant context.
My bet is that you are restarting the device too much. You need to implement different failure modes and different fail-safes than restarting the device on each issue. Likely the device is in a funny state while restart is triggered and then using the device after restart might not behave the way the drivers expect from the device and get stuck.
And I would also remove the comments with the printf and replace it with a #ifdef
then having #define VERBOSE_DEBUG_PRINT so you can enable/disable the debugging quickly.
Another thing I would do is add to the loop this:
Serial.println(ESP.getFreeHeap());
If this is changing between the iterations of the loop, then that is not a good sign and something might be leftover.
I would go over the MQTT library documentation and examples as you might be abusing the library and calling things more frequently or in unexpected places as it was intended. And there might be side effect that I might work most of the times but once in a while either leak a bit of a heap, or get stuck.
You are asking about other projects being able to run without crashes, then look at them and how they are using the MQTT. My guess is that they do not restart device in so many branches and do calls like subscribe in a specific place (like inside the connect, but not inside the main loop). Likely you might be subscribing too much and leaking the memory.
Is 500ms delay for reconection good enough, doesn't it leave the device sometimes in a funny state, it might have be a race condition which happens only sometimes, would increase existing delays by 4x (like 500 to 2000) and add new delays in some places just in case the device expects sometime after the command, and was not expecting to be used in such way like its here (stuff in the loop etc...)
i am trying to make a program that turns on ,off and blinks an led with the help from bluetooth
On and of were pretty easy to replicate,but i can't make the blink to work.There are to options either blinks once,either if i ad a while it never stops from looping.i tried with both if and case.Can somebody help me.I am using an esp32.
The code with if:
#include "BluetoothSerial.h"
#include <Arduino.h>
#include <analogWrite.h>
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif
BluetoothSerial SerialBT;
int received;// received value will be stored in this variable
char receivedChar;// received value will be stored as CHAR in this variable
const char turnON ='a';
const char turnOFF ='b';
const char turnBLINK= 'c';
//const char turnFADE='d';
const int LEDpin = 12;
//int brightStep = 1;
//int brightness = 0;
void setup() {
Serial.begin(115200);
SerialBT.begin("Mono"); //Bluetooth device name
Serial.println("The device started, now you can pair it with bluetooth!");
Serial.println("To turn ON send: a");//print on serial monitor
Serial.println("To turn OFF send: b"); //print on serial monitor
pinMode(LEDpin, OUTPUT);
// analogWriteResolution(LEDpin, 12);
}
void loop() {
receivedChar =(char)SerialBT.read();
if (Serial.available()) {
SerialBT.write(Serial.read());
}
if (SerialBT.available()) {
// while(SerialBT.available()){
// receivedChar =(char)SerialBT.read();
// }
SerialBT.print("Received:");// write on BT app
SerialBT.println(receivedChar);// write on BT app
Serial.print ("Received:");//print on serial monitor
Serial.println(receivedChar);//print on serial monitor
//SerialBT.println(receivedChar);//print on the app
//SerialBT.write(receivedChar); //print on serial monitor
if(receivedChar == turnON)
{
SerialBT.println("LED ON:");// write on BT app
Serial.println("LED ON:");//write on serial monitor
digitalWrite(LEDpin, HIGH);// turn the LED ON
}
if(receivedChar == turnOFF)
{
SerialBT.println("LED OFF:");// write on BT app
Serial.println("LED OFF:");//write on serial monitor
digitalWrite(LEDpin, LOW);// turn the LED off
}
if(receivedChar == turnBLINK)
{
SerialBT.println("LED blink:");// write on BT app
Serial.println("LED blink:");//write on serial monitor
while (receivedChar == turnBLINK){
//receivedChar =(char)SerialBT.read();
//if(receivedChar != turnBLINK){
// break;
// } else {
digitalWrite(LEDpin, HIGH);// turn the LED off
delay(1000);
digitalWrite(LEDpin,LOW);
delay(1000);
if(receivedChar != turnBLINK){
break; }
}
}
}
delay(20);
}
and with case:
#include "BluetoothSerial.h"
#include <Arduino.h>
#include <analogWrite.h>
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif
BluetoothSerial SerialBT;
int received;// received value will be stored in this variable
char receivedChar;// received value will be stored as CHAR in this variable
char data;
int option;
int blink=0;
const int LEDpin = 12;
void setup() {
Serial.begin(115200);
SerialBT.begin("Mono"); //Bluetooth device name
Serial.println("The device started, now you can pair it with bluetooth!");
Serial.println("To turn ON send: 1");//print on serial monitor
Serial.println("To turn OFF send: 0"); //print on serial monitor
pinMode(12, OUTPUT);
}
void loop(){
receivedChar =(char)SerialBT.read();
// if (Serial.available()) {
// SerialBT.write(Serial.read());
// }
if (SerialBT.available()) {
// while(SerialBT.available()){
// receivedChar =(char)SerialBT.read();
// }
SerialBT.print("Received:");// write on BT app
SerialBT.println(receivedChar);// write on BT app
Serial.print ("Received:");//print on serial monitor
Serial.println(receivedChar);//print on serial monitor
//SerialBT.println(receivedChar);//print on the app
//SerialBT.write(receivedChar); //print on serial monitor
data=receivedChar;
if(data == '0')
{
option = 0;
blink=0;
}else if(data == '1')
{
option = 1;
blink=0;
}else if(data == '2')
{
option = 2;
blink=1;
}
switch (option)
{
case 0: // LED OFF
digitalWrite(LEDpin, LOW);
break;
case 1: //LED ON
digitalWrite(LEDpin, HIGH);
break;
case 2:
while(blink=1){// LED BLINK
digitalWrite(LEDpin , HIGH);
delay(200);
digitalWrite(LEDpin, LOW);
delay(200);
}
break;
}
}
}
First of all, you should clean your code to a minimum reproducible example. Remove all unnecessary comments and pieces of code that do not represent the main problem you are facing.
After a quick skim over your code, I immediately noticed this:
while(blink=1){// LED BLINK
digitalWrite(LEDpin , HIGH);
delay(200);
digitalWrite(LEDpin, LOW);
delay(200);
}
where it should be while(blink==1){ } --> very common mistake. This should be a comparison, NOT an assignment.
Now, you mention that it never stops running. Even after correcting the error I just pointed at, what part inside of your while loop breaks the logic of blink from being equal to 1? Otherwise, the while-loop will never stop
Finally, do not read the serial data inside the main loop(). Use SerialEvent, rather.
Again, it is quite tricky to follow the flow of your code. I suggest you divide your code into functions in order to make it more readable.
I am trying to control a LED from Thingspeak server by using the GSM module.
The data received is successfully being printed on serial monitor(which is '1' as last updated) but when I am trying to assign that data to a variable so as to control the inbuilt LED of Arduino, nothing happens.
#include <SoftwareSerial.h>
SoftwareSerial SIM900A(10, 11);
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
SIM900A.begin(9600);
Serial.begin(9600);
while (!Serial)
;
Serial.println("Arduino is ready");
SIM900A.begin(9600);
Serial.println("SIM900A started at 9600");
delay(1000);
Serial.println("Setup Complete");
}
void loop()
{
SIM900A.println("AT");
delay(1000);
ShowSerialData();
SIM900A.println("AT+CIPSHUT");
delay(2000);
ShowSerialData();
SIM900A.println("AT+CIPMUX=0");
delay(2000);
ShowSerialData();
SIM900A.println("AT+CGATT=1");
delay(5000);
SIM900A.println("AT+CSTT=\"INTERNET\",\"\",\"\"");
delay(4000);
SIM900A.println("AT+CIICR");
delay(3000);
ShowSerialData();
SIM900A.println("AT+CIFSR");
delay(5000);
ShowSerialData();
SIM900A.println("AT+CIPSTART=\"TCP\",\"184.106.153.149\",\"80\"");
delay(4000);
ShowSerialData();
SIM900A.println("AT+CIPSEND");
delay(4000);
SIM900A.print("GET /channels/798173/fields/1/last");
SIM900A.print("\r\n\x1A");
ShowSerialData();
char led = SIM900A.read();
Serial.print(led);
if (led == '1')
{
digitalWrite(LED_BUILTIN, HIGH);
}
else if (led == '0')
{
digitalWrite(LED_BUILTIN, LOW);
}
delay(8000);
}
void ShowSerialData()
{
while (SIM900A.available() != 0)
Serial.print(char(SIM900A.read()));
}
Last portion of the output from the serial monitor:
CONNECT OK
AT+CIPSEND
> ⸮GET /channels/798173/fields/1/last
SEND OK
1
As pointed out by #Saurabh P Bhandari, you cannot read the same data from the serial twice, thus you'd need to read the data in a variable in the first place if you wish to use it.
String getSerialData(){
String buffer="";
while (SIM900A.available() ){
char c = SIM900A.read();
buffer+=c;
}
return buffer;
}
Then you can use String led = getSerialData() to populate led with the buffer.
Here, you need to beware that the function getSerialData would return anything present on the buffer and would look something like:
GET /channels/798173/fields/1/last
SEND
HTTP RESPONSE
It appears that you're only interested in HTTP RESPONSE, thus you can update your conditionals to be
if(led.endsWith("1"))
...
else if(led.endsWith("0"))
From what I have understood so far, in this snippet
SIM900A.print("GET /channels/798173/fields/1/last");
SIM900A.print("\r\n\x1A");
ShowSerialData();
ShowSerialData() is printing the output which is '1'. Then immediately your are reading data into the variable led. Since, the actual data received is being printed already from ShowSerialData(), the next time you call SIM900A.read() will return either nothing or next set of data being sent by your module.
You are likely getting rate limited because you are hitting ThingSpeak servers too frequently. You can only update a channel once every 15s with a free account. Obviously, it makes no sense to ask for a value faster than it can be updated, i.e., once every 15s with a free account.
Consider putting some required delays in your code to ensure your device is not blacklisted for abuse of terms.
I am trying to finish a small project with a moisture sensor connected to a Fio V3.
I have also attach a Xbee S1 module to Fio's socket.
I have upload the following code to Fio:
int igrasia = 7;
void setup()
{
Serial1.begin(9600);
pinMode(igrasia, INPUT_PULLUP);
}
void loop(){
int sensorVal = digitalRead(igrasia);
if (sensorVal == HIGH) {
Serial1.println("0"); // Send OK to xbee
}
else {
Serial1.println("1"); // Send NOT OK to xbee
}
delay(5000);
}
On my computer using the Xbee USB explorer I am receiving correct data on X-CTU every 5 seconds.
Zero (0) while the sensor is outside a glass of water and one (1) while the sensor is in the glass of water.
I want to read these bytes to an Arduino Uno with a LCD screen attached and an Xbee shield. For this reason I have uploaded to Uno the following code:
#include <SPI.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x38,16,2); // set the LCD address to 0x20 for a 16 chars
void setup(){
Serial.begin(9600);
//configure pin2 as an input and enable the internal pull-up resistor
// pinMode(8, INPUT_PULLUP);
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
lcd.init(); // initialize the lcd
}
void loop(){
if(Serial.available())
{
char getData = Serial.read();
if (getData == '1')
{
Serial.print(getData);
digitalWrite(13, HIGH);
lcd.clear();
lcd.setCursor (0,0); // go to start of 1st line
lcd.print("ATTENTION !!!!");
lcd.setCursor (0,1); // go to start of 1st line
lcd.print("WET environment");
}
else {
Serial.print(getData);
digitalWrite(13, LOW);
lcd.clear();
lcd.setCursor (0,0); // go to start of 1st line
lcd.print("dry environment");
lcd.setCursor (0,1); // go to start of 1st line
lcd.print("all looks good!");
}
}
}
It doesn't work properly :- (
I have correct functionality for 0 and while the sensor is outside the water. LCD monitor shows "dry environment".
But as soon as I place the sensor in the water, LCD is not working as required.
Even if I leave the sensor in the water the LCD still displays "dry environment".
I tried the sensor connected directly to Uno with the LCD attached and it works!
I suppose something is wrong with the serial.read() and/or my If / loop statement on UNO.
Any suggestions or advice?
When you transmit the data, you're sending it as a String "1", "0".
On the receiver, you're testing for characters '1', '0'. Strings are terminated with a null character (/u0000), whereas characters are not. Therefore the condition is always failed. You could try transmitting and testing characters only.