I have a project that I would like to develop but I am missing some things, specially related with serial communication.
I have read tons of forums but as much I read, more confused I get about it. I am sorry if I am repeating this question.
What I want to do is very simple to understand and to code too, I think... I know it is a quite simple method but I have realised which is the most reliable way to do it.
we start by having 2 arduinos connected via serial, the (lets call) Arduino 1 has 4 pots and 4 switches, it read the pots and switches values, pack it into a group of information like "255,255,255,255,1,1,1,1" (this would be the max values of each one of the sensors) and send this pack to the serial.....
..... now the Arduino 2 receives this pack, decode it to get the separate values and send the pot values (0 to 255) to dim some leds and the switches informations (0 to 1) to control some relays.
So, can somebody suggest me some kind of working code sample or something more clear on how to do it instead of sending me to another topic where I have been before?
Please, try to avoid abstract answers because I am new on this and I am not familiar as I would like to be about arduino coding.
Start by using SoftwareSerial on both Arduinos assuming that the boards do not have 2 or more hardware serial ports. That will enable you to use the hardware serials on the Arduinos to debug your code. Connect the 2 Arduinos together using the pins defined in their SoftwareSerial setups.
Now, forget your eventual aim. Can you send a single, hard code byte from Arduino A to Arduino B, read it and display it ? When you can do that you are ready to move on.
this is sending the mapped pod values over the serial to the arduino 2 which code is this one:
byte byteRead;
const int analogOutPin = 9;
float sensorValue = 0;
float outputValue = 0;
void setup() {
// Turn the Serial Protocol ON
Serial.begin(9600);
}
void loop() {
/* check if data has been sent from the computer: */
if (Serial.available()) {
/* read the most recent byte */
byteRead = Serial.read();
sensorValue = analogRead(byteRead);
analogWrite(analogOutPin, byteRead);
Serial.write(byteRead);
}
}
As I have read in other posts, what I am getting are ASCII through the serial and, I don't know the way to "translate" this ASCII to numeric and keep the value of 0-255 for the pot value in the receiving arduino... I can see the good numbers in the Serial Monitor because I am using the "Serial.write" but, as everybody knows, if I change it to Serial.print I will get the values that are really being sent to the led output which are number like 13, 10, 49, 53 and so on (ASCII)....
This is just one of the problems I have, but at least I have communication between the 2 boards and monitoring for debugging, now we can go straight to the working code, please...
The other problem for which I need a solution is on how to pack all the data on the outgoing arduino and unpack and interpret that pack of information on the receiving arduino in order to put the leds and the relays to work.
You don't need to pack the data on the sending Arduino beyond adding a "start of message" indicator, a dividing character between each value and an "end of message" indicator at the end of the message. Most of the work then takes place on the receiving Arduino. This will be a good place to start in order to build a string on the receiving Arduino that you can then take apart using the strtok() function using the dividing characters that you added before transmission. Gammon Forum : Electronics : Microprocessors : How to process incoming serial data without blocking
Is it a good idea to use the same serial interface for receiving data and writing to the serial output ?
Yes, you are right, I have managed to "print" all the values arranged on the way I need, as I have written before, like 122,203,68,0,1,1,0,1 (pot,pot,pot,pot,sw,sw,sw,sw), now, as you said, the hard work is to get this pack and apply the right value AS A NUMBER into its respective output.... Thats where I am and I am facing some difficulties to go over it.
I have seen your link very fast and, as it is a complete code, I am not understanding where and what is doing the function you mentioned. I don't deal with arduinos on a daily base.... sorry
I recently had success with a master and slave arduino. The master sends a "*" as a data request and the slave then sends data back:
Master code:
String readString; //make global.
uint8_t valueA, valueB;
void setup() {
Serial.begin(19200);
}
void loop() {
Serial.println(F("*"));
delay (1000);
}
void serialEvent(){ //is called any time serial data is available
while(Serial.available()){
char c = Serial.read();
readString += c;
if (c == "*") {
uint8_t = readString.indexOf('a'); //gets position of "a".
uint8_t = readString.indexOf('b'):
String firstString = readString.substring(0, a); //makes a new string called "firstString" and stores all the characters from position 0 to a.
valueA = firstString.toInt(); //converts to int.
String secondString = readString.substring(a + 1, b) //makes a new string called "secondString and stores all the numbers from a + 1 to b.
valueB = secondString.toInt();
readString = ""; //clears string once all data recieved and decoded.
}
Slave code:
uint8_t valueA, valueB;
void setup() {
Serial.begin(19200); //MUST be same baud rate.
}
void loop() {
valueA = analogRead(0) / 4; //keep within 0-255
delay(10); //needed between analog readings
valueB = analogRead(1) / 4;
delay(10);
}
void serialEvent() {
char c = Serial.read();
switch (c) {
case '*': //all data requested
Serial.print(valueA);
Serial.print("a");
Serial.print(valueB);
Serial.print("b");
Serial.println("*"); //end of string.
break;
case 'a': //a single character command from master
//do something.
break;
}
}
The master sends a data request every second. The slave, which is just doing its thing until a command is recieved, sends its data back as a string with markers indicating the end of a value if the command is "*". If you send it an "a", it will do something else then continue back to the main loop doing its thing. The master then decodes the string by finding the position of each data marker and converts the characters to a new string, then converts that string to an integer.
Hi, well, I got my hands on the arduino but something on the "Master" side is not working and I am not realising what (lack of experience coding), sorry...
This is the "Slave" code which is working;
int pot1;
int pot2;
void setup() {
Serial.begin(9600); //MUST be same baud rate.
}
void loop() {
pot1 = analogRead(0) / 4; //keep within 0-255
delay(5); //needed between analog readings
pot2 = analogRead(1) / 4;
delay(5);
serialEvent();
}
void serialEvent() {
// char c = Serial.read();
// switch (c) {
// case '*': //all data requested
Serial.print("a");
Serial.print(pot1);
Serial.print("b");
Serial.print(pot2);
Serial.println("*"); //end of string.
// break;
// case 'a': //a single character command from master
//do something.
// break;
// }
}
This is the "Master" code and I am having an issue to compile:
String readString; //make global.
int a;
int b;
int pot1;
int pot2;
String Pots[] = {"a", "b"};
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println(F(","));
delay (10);
if(Serial.available()) {
// char c = Serial.read();
// readString += c;
// if (c == '*') {
Pots = readString.indexOf("a"); //gets position of "a".
Pots = readString.indexOf("b");
String firstString = readString.substring(0, a); //makes a new string called "firstString" and stores all the characters from position 0 to a.
pot1 = firstString.toInt(); //converts to int.
String secondString = readString.substring(a + 1, b); //makes a new string called "secondString and stores all the numbers from a + 1 to b.
pot2 = secondString.toInt();
readString = ""; //clears string once all data recieved and decoded.
Serial.print(",");
//}
analogWrite(9, pot1);
analogWrite(10, pot2);
}
}
There are a lot of reasons its not working. You have a lot of code commented out and in the wrong places. Try uploading the code exactly how I wrote it and see if it works that way.
serialEvent() should NOT be in the main loop. It gets called automatically when ever there is serial data available. You should have the slave wait until data is requested before sending data back.
I have been testing only with one pot and one led and everything works perfect but, when I attach the second pot and led it doesn't work. It seams that the code is getting the value "a" but not the value "b"...
I have checked the connections several times and are all correct, maybe the code you wrote is not getting the "b" as it should.
I bet the issue is that you're sending too many commands over serial by shortening the master code delay. Try increasing that amount to 100 ms or so and see if it works.