Serial.Read() code - c++

HI I would like to control 8 x Pumps with Bluetooth on my arduino... I whant to change number '1' for 'ON' to '1on' and '2' for 'OFF' to '1off', than
'2on' , '2off' ,
'3on' , '3off' etc. but I don't know how because I'm not a coder... Here is my code:
int PUMP1 = 2;
int PUMP2 = 3;
char value = 0;
void setup()
{
Serial.begin(9600);
pinMode(PUMP1, OUTPUT);
pinMode(PUMP2, OUTPUT);
}
void loop()
{
if (Serial.available())
{
value = Serial.read();
if (value == '1') digitalWrite(PUMP1, LOW); //relay1 on
else if (value == '0') digitalWrite(PUMP1, HIGH); //relay1 off
if (value == '3') digitalWrite(PUMP2, LOW); //relay2 on
else if (value == '2') digitalWrite(PUMP2, HIGH); //relay2 off
}
}

You need to replace Serial.read() with Serial.readStringUntil('\n'). The strings will need to be sent with a trailing new line character.
void loop()
{
if (Serial.available())
{
String value = Serial.readStringUntil('\n');
if (value == "1on") digitalWrite(PUMP1, LOW); //relay1 on
else if (value == "1off") digitalWrite(PUMP1, HIGH); //relay1 off
else if (value == "2on") digitalWrite(PUMP2, LOW); //relay2 on
else if (value == "2off") digitalWrite(PUMP2, HIGH); //relay2 off
// and so on
}
}
Serial.readString() was suggested in the comments, but that will lead to 1 sec of delay (by default). In this case the string is considered complete when there is no data for certain amount of time. And it will be impossible to control multiple relays at the same time.

Related

C++ Assignment - Why isn't the push button working?

I am trying to do the following on an Arduino:
Task: Create a toggle switch that controls when 3 LEDs switch on (at the same time). In a toggle switch, when the button is pressed, the LEDs switch on. When it is pressed again, the LEDs switch off.
My pushbutton isn't turning on to turn on the LEDs
The code is:
// C++ code
//Declare
int ledPin13 = 13;
int ledPin12 = 12;
int ledPin11 = 11;
int buttonPin = 1;
int buttonState;
//State if input or output
void setup() {
pinMode(buttonPin , INPUT);
pinMode(ledPin13 , OUTPUT);
pinMode(ledPin12 , OUTPUT);
pinMode(ledPin11 , OUTPUT);
}
//Stage 3 - Code what you want to do (according to psuedocode)
void loop() {
buttonState = digitalRead(buttonPin);
if(buttonState == HIGH) {
digitalWrite(ledPin13 , HIGH);
digitalWrite(ledPin12 , HIGH);
digitalWrite(ledPin11 , HIGH);
}
else {
digitalWrite(ledPin13 , LOW);
digitalWrite(ledPin12 , LOW);
digitalWrite(ledPin11 , LOW);
}
}
It is because your program continuously reads a state. It means the time of pressing the button in compare with the checking of the state by MCU is too mush . for fixing this problem you have two options:
Checking the button. You have to check the state but It is better
to use debouncing which means adding delay between two reads.
bool LEDstate = false;
void loop()
{
if (digitalRead(buttonPin) == HIGH)
{
delay(500); // to be stable
if (digitalRead(buttonPin) == HIGH)
{
if (LEDstate == false)
{
digitalWrite(ledPin13, HIGH);
digitalWrite(ledPin12, HIGH);
digitalWrite(ledPin11, HIGH);
LEDstate = true;
}
else
{
digitalWrite(ledPin13, LOW);
digitalWrite(ledPin12, LOW);
digitalWrite(ledPin11, LOW);
LEDstate = false;
}
while (digitalRead(buttonPin) == HIGH); // wait to release
}
}
}
Inverse reading, which means you have to read the pressing and then wait to release to change the state of LEDs
bool LEDstate = false;
void loop()
{
if (digitalRead(buttonPin) == HIGH)
{
delay(100); // to be stable
while (digitalRead(buttonPin) == HIGH); // wait to release
if (LEDstate == false)
{
digitalWrite(ledPin13, HIGH);
digitalWrite(ledPin12, HIGH);
digitalWrite(ledPin11, HIGH);
LEDstate = true;
}
else
{
digitalWrite(ledPin13, LOW);
digitalWrite(ledPin12, LOW);
digitalWrite(ledPin11, LOW);
LEDstate = false;
}
}
}
bool toggleState = 0;
buttonState = digitalRead(buttonPin);
delay(100);
if( buttonState == 1)
{
if(toggleState)
toggleState = 0;
else
toggleState = 1;
}
if(toggleState)
{
digitalWrite(ledPin13 , HIGH);
digitalWrite(ledPin12 , HIGH);
digitalWrite(ledPin11 , HIGH);
}
else
{
digitalWrite(ledPin13 , LOW);
digitalWrite(ledPin12 , LOW);
digitalWrite(ledPin11 , LOW);
}

Serial Communication freezes with BMP180 and Arduino Mega

I recently bought an ELEGO Mega 2560, or in other words an Arduino Mega. I bought a bmp180 sensor as well. I connected the bmp in this fashion, VCC - 3.3v, GND - GND, SCL - 21, SDA - 20. I uploaded a simple code which just displayes altitude. When I go to the Serial Monitor to view the results, nothing pops up. It is suppose to say BMP init success if it connects, and fail if it doesn't. When I go to the monitor, it just doens't say anything. When I disconnect the sensor, it says fail. It appears as if the Serial Monitor just freezes. Also a headsup, my code is very messy, I'm sorry if it's hard to keep up.
#include <Wire.h>
#include <SFE_BMP180.h>
SFE_BMP180 bmp180;
float Po = 1014.9;
#define ledPin 7
#define TransmitPin 5
//int Altitude = 5;
int sendValue;
String incomingString;
unsigned long lastTransmission;
const int interval = 1000;
void setup() {
Wire.begin();
pinMode(ledPin, OUTPUT);
pinMode(2, INPUT);
pinMode(10, OUTPUT);
pinMode(TransmitPin, OUTPUT);
bool success = bmp180.begin();
Serial.begin(115200);
if (success) {
Serial.println("BMP180 init success");
}
else
Serial.println("fail");
}
void loop() {
sendValue = digitalRead(29);
if (sendValue == HIGH) {
if (millis() > lastTransmission + interval) {
Serial.println("AT+SEND=1,8,Return");
digitalWrite(TransmitPin, HIGH);
delay(100);
digitalWrite(TransmitPin, LOW);
lastTransmission = millis();
}
}
if (Serial.available()) {
incomingString = Serial.readString();
if (incomingString.indexOf("Testing!") > 0) {
digitalWrite(10, HIGH);
delay(100);
digitalWrite(10, LOW);
}
}
char status;
double T, P, alt;
bool success = false;
status = bmp180.startTemperature();
if (status != 0) {
delay(1000);
status = bmp180.getTemperature(T);
if (status != 0) {
status = bmp180.startPressure(3);
if (status != 0) {
delay(status);
status = bmp180.getPressure(P, T);
if (status != 0) {
if (millis() > lastTransmission + interval) {
alt = bmp180.altitude(P, Po);
Serial.print("AT+SEND=1,8,");
int altAsFoot = alt * 3.281;
Serial.println(altAsFoot);
digitalWrite(TransmitPin, HIGH);
delay(100);
digitalWrite(TransmitPin, LOW);
}
for (int i = 0; i < 1800; i++) {
delay(1);
if (Serial.available()) {
incomingString = Serial.readString();
if (incomingString.indexOf("+OK") > 0) {
digitalWrite(ledPin, HIGH);
delay(100);
digitalWrite(ledPin, LOW);
}
if (incomingString.indexOf("Testing!") > 0) {
digitalWrite(10, HIGH);
delay(100);
digitalWrite(10, LOW);
}
}
}
}
}
}
}
}
Turns out it was a hardware issue. I had ground shorted to SDA. I'm assuming the same will happen if it's shorted to SCL. Make sure both SDA and SCL aren't shorted to each other or ground.

Arduino base 2 calculator not working C++

This is my code for an Arduino, I think the problem is the input(//nr1 and //nr2) because it worked before changing it to its current state. Thank you for helping in advance!
int nr1 = 0;
int nr2 = 0;
int rs = 0;
void setup() {
// put your setup code here, to run once:
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(9, INPUT);
pinMode(10, INPUT);
pinMode(11, INPUT);
pinMode(12, INPUT);
}
void loop()
{
//nr1
if(digitalRead(11)==LOW && digitalRead(12)==LOW)
{
nr1 = 0;
} else if(digitalRead(11)==LOW && digitalRead(12)==HIGH)
{
nr1 = 1;
} else if(digitalRead(11)==HIGH && digitalRead(12)==LOW)
{
nr1 = 2;
} else if(digitalRead(11)==HIGH && digitalRead(12)==HIGH)
{
nr1 = 3;
}
//nr2
if(digitalRead(9)==LOW && digitalRead(10)==LOW)
{
nr1 = 0;
} else if(digitalRead(9)==LOW && digitalRead(10)==HIGH)
{
nr1 = 1;
} else if(digitalRead(9)==HIGH && digitalRead(10)==LOW)
{
nr1 = 2;
} else if(digitalRead(9)==HIGH && digitalRead(10)==HIGH)
{
nr1 = 3;
}
//rs
rs= nr1 + nr2;
if(rs>4)
{
digitalWrite(2, HIGH);
}else
{
digitalWrite(2, LOW);
}
if(rs%4==2)
{
digitalWrite(3, HIGH);
digitalWrite(4, LOW);
}
if(rs%4==1)
{
digitalWrite(3, LOW);
digitalWrite(4, HIGH);
}
if(rs%4==0)
{
digitalWrite(3, LOW);
digitalWrite(4, LOW);
}
delay(1000);
nr1=0;
nr2=0;
rs=0;
}
In your loop, you never assign nr2 a value.
Maybe you want this:
const unsigned int pin9 = (digitalRead(9) == LOW) ? 0 : 1;
const unsigned int pin10 = (digitalRead(10) == LOW) ? 0 : 1;
nr2 = pin10 << 1 | pin9;
The above code fragment reads pin 9 and 10 once, converts them into a one or zero, then calculates nr2 based on the values of pin 9 and 10.
You can try to assign the digitalRead values ​​to a variable and use it within the ifs, this will cause you to read the digital pin value previously, start by trying something like state12 = digitalRead (12); and inside the if do something like
if (state12 == HIGH)...

Keypad 4*4 with Arduino

I am using keypad 4*4 with an Arduino Mega, I have sensors connected to the Arduino I want to press a key from the keypad and have response in the same time, I don't want to wait till the loop continue, I want to save up to 10 numbers entered from the keypad, so is there a way to make the keypad as an interrupt for my code?
void loop()
{
char key = kpd.getKey();
if (key != NO_KEY) {
if (key == 'C') //clear the array
{
index = 0;
numbers[index] = '\0';
}
else if (key == '.') {
numbers[index++] = '.';
numbers[index] = '\0';
}
else if (key >= '0' && key <= '9') {
for (int z = 0; z == 10; z++) {
numbers[index++] = key;
numbers[index] = '\0';
}
}
else if (key == 'A') {
float len = atof(numbers); //conversion from string to numeric
if (fona.callPhone(numbers)) {
Serial.println(F("RING!"));
Serial.print(F("Phone Number: "));
Serial.println(numbers); //print out on serial monitor
}
}
else if (key == 'D') {
if (fona.pickUp()) {
Serial.println(F("Failed"));
}
}
else if (key == '#') {
if (fona.hangUp()) {
Serial.println(F("Failed"));
}
}
}
gas = analogRead(gasPin);
dtostrf(gas, 4, 2, gass);
Serial.println(gas);
delay(1000); // Print value every 1 sec.
val = digitalRead(inputPin); // read input value
if (val == HIGH) { // check if the input is HIGH
digitalWrite(ledPin, HIGH); // turn LED ON
delay(150);
if (pirState == LOW) {
// we have just turned on
Serial.println("Motion detected!");
// We only want to print on the output change, not state
pirState = HIGH;
}
}
else {
digitalWrite(ledPin, LOW); // turn LED OFF
delay(300);
if (pirState == HIGH) {
// we have just turned off
Serial.println("Motion ended!");
// We only want to print on the output change, not state
pirState = LOW;
}
}
int ldrStatus = analogRead(ldrPin);
if (ldrStatus <= 550) {
digitalWrite(led, HIGH);
Serial.println("LDR is DARK, LED is ON");
}
else {
digitalWrite(led, LOW);
}
valee = analogRead(tempPin);
float cel = (valee * 0.48828125) / 2.12304;
dtostrf(cel, 4, 2, temp);
Serial.print("TEMPRATURE = ");
Serial.print(cel);
Serial.print("*C");
Serial.println();
delay(1000);

Callback function not executing second statement - C++ MQTT

I've programmed a callback function that handles MQTT messages (payload). I want to switch of pins not based on an incoming payload. The problem I have now is that the first statement is executed nicely when sending 11. However the second statement is not working. Strangely when I send two messages one containing 1x and the other x1 I can again toggle both pins. It's a very strange problem!
Could anyone help me with this, thanks very much. I'm using the PubSubClient library.
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
//Set GPIO0 to HIGH or LOW on first character received in message
if (payload[0] == '1') {
digitalWrite(GPIO0, HIGH); // Turn the relay on
client.publish(getOutTopic().c_str(), "GPIO0 set to HIGH");
} else if (payload[0] == '0') {
digitalWrite(GPIO0, LOW); // Turn the relay off
client.publish(getOutTopic().c_str(), "GPIO0 set to LOW");
}
//Set GPIO2 to HIGH or LOW on first character received in message
if (payload[1] == '1') {
digitalWrite(GPIO2, HIGH); // turn LED off. With High it is inactive on the ESP-01)
client.publish(getOutTopic().c_str(), "GPIO2 set to HIGH");
} else if (payload[1] == '0') {
digitalWrite(GPIO2, LOW); // Turn the LED on by making the voltage LOW
client.publish(getOutTopic().c_str(), "GPIO2 set to LOW");
}
}
The client.publish destroys the payload buffer. So I had to catch the payloads into new variables to overcome the problem.
void callback(char* topic, byte* payload, unsigned int length) {
char p0 = (char)payload[0];
char p1 = (char)payload[1];
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
//Set GPIO0 to HIGH or LOW on first character received in message
if (p0 == '1') {
digitalWrite(GPIO0, HIGH); // Turn the relay on
client.publish(getOutTopic().c_str(), "GPIO0 set to HIGH");
} else if (p0 == '0') {
digitalWrite(GPIO0, LOW); // Turn the relay off
client.publish(getOutTopic().c_str(), "GPIO0 set to LOW");
}
//Set GPIO2 to HIGH or LOW on first character received in message
if (p1 == '1') {
digitalWrite(GPIO2, HIGH); // turn LED off. With High it is inactive on the ESP-01)
client.publish(getOutTopic().c_str(), "GPIO2 set to HIGH");
} else if (p1 == '0') {
digitalWrite(GPIO2, LOW); // Turn the LED on by making the voltage LOW
client.publish(getOutTopic().c_str(), "GPIO2 set to LOW");
}
}