Serial message to integer on Arduino - serial-port

I want my Arduino to receive an integer through the serial communication. Can you help me with this?
It should be in a form like:
int value = strtoint(Serial.read());

There are several ways to read an integer from Serial, largely depending on how the data is encoded when it is sent. Serial.read() can only be used to read individual bytes so the data that is sent needs to be reconstructed from these bytes.
The following code may work for you. It assumes that serial connection has been configured to 9600 baud, that data is being sent as ASCII text and that each integer is delimited by a newline character (\n):
// 12 is the maximum length of a decimal representation of a 32-bit integer,
// including space for a leading minus sign and terminating null byte
byte intBuffer[12];
String intData = "";
int delimiter = (int) '\n';
void setup() {
Serial.begin(9600);
}
void loop() {
while (Serial.available()) {
int ch = Serial.read();
if (ch == -1) {
// Handle error
}
else if (ch == delimiter) {
break;
}
else {
intData += (char) ch;
}
}
// Copy read data into a char array for use by atoi
// Include room for the null terminator
int intLength = intData.length() + 1;
intData.toCharArray(intBuffer, intLength);
// Reinitialize intData for use next time around the loop
intData = "";
// Convert ASCII-encoded integer to an int
int i = atoi(intBuffer);
}

You may use the Serial.parseInt() function, see here: http://arduino.cc/en/Reference/ParseInt

Related

Convert "String" above 255 to exact "Integer" or "Long" type in Arduino IDE

Appreciate your time.
I am trying to convert "String" read from serial port in serialEvent() of Arduino IDE to integer values with exact representation.
For eg, if String myString = 200 then int myInt should be 200.
I have been somewhat successful but unable to convert String to exact int representation beyond 255.
Solutions I have tried:
1) used .toInt() function in Arduino.
2) used "atoi" and "atol" functions.
3) Serial.parseInt() in loop().
All of these methods start recounting from 0 after every 255 values.
I can't use parseInt since it only works inside loop(). My application requires to store variable value permanently until another value is given through port. For this Arduino Due's flash memory has been used.
The memory storing code seems to work only inside serialEvent().
Code snippet is as below:
#include <stdlib.h>
#include <DueFlashStorage.h>
DueFlashStorage memory;
String x = " ";
int x_size;
int threshold;
void setup(){
Serial.begin(115200);
}
void loop{
Serial.println(memory.read(0));
}
void serialEvent(){
while(Serial.available()){
x = Serial.readStringUntil('\n');
x_size = x.length();
char a[x_size+1];
x.toCharArray(a, x_size+1);
threshold = atoi(a);
memory.write(0, threshold);
}
}
1) Function .toInt() returns LONG and you want INT (I don't know why honestly but it is in documentation)... you need to cast it like this (tried on Arduino ATMEGA and it worked):
#include <stdlib.h>
String x = "1000";
int x_ = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
x_ = (int) x.toInt();
Serial.println(x_);
delay(1000);
}
2) I’m not professional ... but serilEvent() is really old way of doing things and it isn't recommended to use it. You can do it "manually" in the loop() function.
You're only converting 1 character a time, that's why the limit is 255.
If you're not doing anything else, you could stay in a serial.read-loop until all characters are read. For example:
void loop() {
if(Serial.available()) {
byte count = 0;
char number[10]; // determine max size of array
bool wait = true;
while(wait) { // stay in this loop until newline is read
if(Serial.available()) {
number[count] = Serial.read();
if (number[count] == '\n') {
wait = false; // exit while loop
}
count++;
}
}
int threshold = atoi(number);
memory.write(0, threshold);
}
}
For the lack of a good function in Arduino IDE for char/String type to int type conversion (has a limit of 255), I wrote my own conversion code which seems to work perfectly.
int finalcount=0;
void setup(){
Serial.begin(115200);
}
void loop(){
if(Serial.available()) {
int count = 0;
char number[5]; // determine max size of array as 5
bool wait = true;
while(wait) { // stay in this loop until newline is read
if(Serial.available()) {
number[count] = Serial.read();
if (number[count] == '\n') {
finalcount = count; //max array size for integer; could be less than 5
wait = false; // exit while loop
}
count++;
}
}
int val[finalcount]; //array size determined for integer
int placeValue;
int finalval[finalcount];
int temp=0;
int threshold;
for(int i = 0; i<finalcount; i++){
val[i] = (int)number[i]-48; //convert each char to integer separately
placeValue = pow(10,(finalcount-1)-i); //calculate place value with a base of 10
finalval[i] = val[i]*placeValue; //update integers with their place value
temp += finalval[i] ; //add all integers
threshold = temp; //resulting number stored as threshold
}
Serial.println(threshold); //prints beyond 255 successfully !
}
}
I solved the problem using highByte and lowByte functions of Arduino. Works flawlessly.
#include <DueFlashStorage.h>
DueFlashStorage m;
byte a1,a2;
int val;
void setup() {
Serial.begin(115200); //start the serial communication
}
void loop()
{
if (Serial.available()>0)
{
val = Serial.parseInt(); //read the integer value from series
if(val>0){
a1 = highByte(val); //get the higher order or leftmost byte
a2 = lowByte(val); //get the lower order or rightmost byte
m.write(0,a1); //save in arduino due flash memory address 0
m.write(1,a2); //save in arduino due flash memory address 1
}
int myInteger;
myInteger = (m.read(0)*256)+m.read(1); //convert into the true integer value
Serial.println(myInteger);
}

Sending array data from Processing to Arduino

I successfully managed to send a single integer from processing to Arduino but now I want to send an array of three integers and I can't get it working. I want to create a buzzer feedback with Arduino which processing will control which buzzer to activate. For example, the data send from processing should be [1,0,1] meaning sensor 1 and 3 should start working. The buzzers should be able to be activated simultaneously in case that [1,1,1] goes through.
This is the code I have so far:
I am trying to understand what data is being sent back to Arduino to know how to use it and I keep getting either a null value or a random integer.
I'm trying to learn how to do this so apologies if the code is bad.
Arduino
void setup(){
Serial.begin(9600); // Start serial communication at 9600 bps
}
void loop(){
if (Serial.available()){
const char data = Serial.read();
char noteBuzzer[] = {data};
for (int i = 0 ; i < sizeof(noteBuzzer); i++) {
}
Serial.print(noteBuzzer[1]);
}
}
Processing
import processing.serial.*;
String notes[];
String tempo[];
Serial myPort;
String val;
void setup(){
size(200,200);
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
notes = loadStrings("data/notes.txt");
tempo = loadStrings("data/tempo.txt");
}
void draw() {
if (keyPressed == true)
{
if (key == '1') {
println("Start");
readNotes();
}
}
}
void readNotes(){
for (int i = 0 ; i < notes.length; i++) {
println(notes[i]);
//println(tempo[i]);
myPort.write(notes[i]);
delay(int(tempo[i])); //this will be the tempo?
if ( myPort.available() > 0)
{
val = myPort.readStringUntil('\n');
println("Arduino",val);
}
}
}
If you're data is an array that always has 3 items and each of those items are always either 1 or 0 (bits), you could store that whole data in a single byte (and still have 5 more bits to spare). Sending and receiving a byte is pretty simple with Arduino.
Here's a basic sketch that shows you how to flip 3 bits in a single byte:
// the state as a byte
byte buzzerState = 0B000;
void setup(){
textFont(createFont("Courier New",18),18);
}
void draw(){
background(0);
text("DEC: " + buzzerState +
"\nBIN:" + binary(buzzerState,3),10,40);
}
void keyPressed(){
if(key == '1'){
buzzerState = flipBit(buzzerState,0);
}
if(key == '2'){
buzzerState = flipBit(buzzerState,1);
}
if(key == '3'){
buzzerState = flipBit(buzzerState,2);
}
}
// flips a bit at a given index within a byte and returns updated byte
byte flipBit(byte state,int index){
int bit = getBitAt(state,index);
int bitFlipped = 1 - bit;
return setBitAt(state,index,bitFlipped);
}
// returns the integer value of a bit within a byte at the desired index
int getBitAt(byte b,int index){
index = constrain(index,0,7);
return b >> index & 1;
}
// sets an individual bit at a desired index on or off (value) and returns the updated byte
byte setBitAt(byte b,int index, int value){
index = constrain(index,0,7);
value = constrain(value,0,1);
if(value == 1) b |= (1 << (index));
else b &= ~(1 << (index));
return b;
}
Use keys '1','2' and '3' to flip the bits.
Note that in keypress we're always updating the same byte.
The text will display the decimal value first and the binary value bellow.
This is the most efficient way to send your data and the simplest in terms of serial communication. On the Arduino side you can simply use bitRead() on the byte you get from Serial.read(). For more on binary/bits/bytes be sure to read the BitMath Arduino tutorial. Binary may seem intimidating at first, but it's really not that bad once you practice a bit and it's totally worth knowing.
Here's an updated version of the code above that sends the byte to Arduino on the first available serial port (be sure to change Serial.list()[0] with what makes sense for your setup and press 's' to send an update to Arduino:
import processing.serial.*;
// the state as a byte
byte buzzerState = 0B000;
Serial port;
void setup(){
textFont(createFont("Courier New",18),18);
try{
port = new Serial(this,Serial.list()[0],9600);
}catch(Exception e){
e.printStackTrace();
}
}
void draw(){
background(0);
text("DEC: " + buzzerState +
"\nBIN:" + binary(buzzerState,3),10,40);
}
void keyPressed(){
if(key == '1'){
buzzerState = flipBit(buzzerState,0);
}
if(key == '2'){
buzzerState = flipBit(buzzerState,1);
}
if(key == '3'){
buzzerState = flipBit(buzzerState,2);
}
if(key == 's'){
if(port != null){
port.write(buzzerState);
}else{
println("serial port is not open: check port name and cable connection");
}
}
}
// flips a bit at a given index within a byte and returns updated byte
byte flipBit(byte state,int index){
int bit = getBitAt(state,index);
int bitFlipped = 1 - bit;
return setBitAt(state,index,bitFlipped);
}
// returns the integer value of a bit within a byte at the desired index
int getBitAt(byte b,int index){
index = constrain(index,0,7);
return b >> index & 1;
}
// sets an individual bit at a desired index on or off (value) and returns the updated byte
byte setBitAt(byte b,int index, int value){
index = constrain(index,0,7);
value = constrain(value,0,1);
if(value == 1) b |= (1 << (index));
else b &= ~(1 << (index));
return b;
}
And here's a super basic Arduino sketch:
byte buzzerState;
void setup() {
Serial.begin(9600);
//test LEDs setup
pinMode(10,OUTPUT);
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
}
void loop() {
if(Serial.available() > 0){
buzzerState = Serial.read();
bool bit0 = bitRead(buzzerState,0);
bool bit1 = bitRead(buzzerState,1);
bool bit2 = bitRead(buzzerState,2);
//test LEDs update
digitalWrite(10,bit0);
digitalWrite(11,bit1);
digitalWrite(12,bit2);
}
}
If you connect 3 LEDs to pins 10,11,12 you should them toggle as you press keys '1','2','3' then 's' in Processing
One way around binary in Processing could be using a String representation of your data (e.g. "00000101" for [1,0,1]) and unbinary() to convert that String to an integer value you can write to serial, but it will be a bit annoying to getting and setting a character at an index (and potentially parsing that char to it's integer value and back)
When you need to send more than a byte things get a bit more complicated as you need to handle data corruption/interruptions, etc. In these situations it's best to setup/design a communication protocol based on your needs and this isn't easy if you're just getting started with Arduino, but not impossible either. Here's an example, there are many more online.
One quick and dirty thing you could try is sending that data as string terminated by a new line character (\n) which you could buffer until in Arduino then read 4 bytes at a time, discarding the \n when parsing:
e.g. sending "101\n" from Processing, representing [1,0,1] then on the Arduino side use Serial.readStringUntil('\n') and a combination of charAt() and toInt() to access each integer within that that string.
Here's an example Processing sketch:
import processing.serial.*;
// the state as a byte
String buzzerState = "010\n";
Serial port;
void setup(){
textFont(createFont("Courier New",18),18);
try{
port = new Serial(this,Serial.list()[0],9600);
}catch(Exception e){
e.printStackTrace();
}
}
void draw(){
background(0);
text(buzzerState,30,50);
}
void keyPressed(){
if(key == '1'){
buzzerState = flipBit(buzzerState,0);
}
if(key == '2'){
buzzerState = flipBit(buzzerState,1);
}
if(key == '3'){
buzzerState = flipBit(buzzerState,2);
}
if(key == 's'){
if(port != null){
port.write(buzzerState);
}else{
println("serial port is not open: check port name and cable connection");
}
}
}
String flipBit(String state,int index){
index = constrain(index,0,2);
// parse integer from string
int bitAtIndex = Integer.parseInt(state.substring(index,index+1));
// return new string concatenating the prefix (if any), the flipped bit (1 - bit) and the suffix
return state = (index > 0 ? state.substring(0,index) : "") + (1 - bitAtIndex) + state.substring(index+1);
}
And an Arduino one based on Arduino > File > Examples > 04.Communication > SerialEvent:
/*
Serial Event example
When new serial data arrives, this sketch adds it to a String.
When a newline is received, the loop prints the string and
clears it.
A good test for this is to try it with a GPS receiver
that sends out NMEA 0183 sentences.
Created 9 May 2011
by Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/SerialEvent
*/
String inputString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
void setup() {
// initialize serial:
Serial.begin(9600);
// reserve 200 bytes for the inputString:
inputString.reserve(200);
// test LEDs setup
pinMode(10,OUTPUT);
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
}
void loop() {
// print the string when a newline arrives:
if (stringComplete) {
Serial.println(inputString);
// process string
bool bit0 = inputString.charAt(2) == '1';
bool bit1 = inputString.charAt(1) == '1';
bool bit2 = inputString.charAt(0) == '1';
//test LEDs update
digitalWrite(10,bit0);
digitalWrite(11,bit1);
digitalWrite(12,bit2);
// clear the string:
inputString = "";
stringComplete = false;
}
}
/*
SerialEvent occurs whenever a new data comes in the
hardware serial RX. This routine is run between each
time loop() runs, so using delay inside loop can delay
response. Multiple bytes of data may be available.
*/
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == '\n') {
stringComplete = true;
}
}
}
Note this is more prone to error and used 4 times as much data as the the single byte option.

Arduino readString(); code runs slow

I have the following code which I need to execute quickly, yet its taking a lot of time to change the value, anyway over way of making this task quicker?
I am using indexOf() and substring() to accomplish this task.
This is for changing the strip LED colors.
// declare LED Series A Pins R-G-B (PWM Pins)
int const AledRedPin = 6;
int const AledGreenPin = 5;
int const AledBluePin = 3;
// declare LED Series B Pins R-G-B (PWM Pins)
int const BledRedPin = 10;
int const BledGreenPin = 11;
int const BledBluePin = 9;
// serial input variable & string
// initialise LED Series A Pins R-G-B (PWN Value: 0 to 255)
// initial value = 255
int AledRed = 255;
int AledGreen = 255;
int AledBlue = 255;
// initialise LED Series A Pins R-G-B (PWN Value: 0 to 255)
// initial value = 255
int BledRed = 255;
int BledGreen = 255;
int BledBlue = 255;
//serial input
String Command = "";
//string manipulation
int cmdindexval = 0;
String CommandType = "";
int CommandValue = 0;
String Series = "";
void setup() {
// put your setup code here, to run once:
// start serial
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB
}
// set LED Series A Pins as Output R-G-B
pinMode(AledRedPin, OUTPUT);
pinMode(AledGreenPin, OUTPUT);
pinMode(AledBluePin, OUTPUT);
// set LED Series B Pins as Output R-G-B
pinMode(BledRedPin, OUTPUT);
pinMode(BledGreenPin, OUTPUT);
pinMode(BledBluePin, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
// read from serial if it's available
if (Serial.available() > 0) {
Command = Serial.readString(); //read string from serial monitor
cmdindexval = Command.indexOf('='); //read characters until '=' then assign the value
CommandType = Command.substring(0, cmdindexval); //assign the value from 0 to cmdindexval
//Series = Command.substring(0, 1); //read first character
CommandValue = Command.substring(cmdindexval + 1).toInt(); //assign the value after '=' and convert string to Int
Serial.println(CommandType + " ,is equal to " + CommandValue + " ,Series: " + Series);
//if (Series == "A") {
if (CommandType == "ACledRed"){
AledRed = CommandValue;
}
else if (CommandType == "ACledGreen"){
AledGreen = CommandValue;
}
else if (CommandType == "ACledRedBlue") {
AledBlue = CommandValue;
}
//}
//else if (Series == "B") {
if (CommandType == "BCledRed") {
BledRed = CommandValue;
}
else if (CommandType == "BCledGreen") {
BledGreen = CommandValue;
}
else if (CommandType == "BCledBlue") {
BledBlue = CommandValue;
}
//}
} //end serial
analogWrite(AledRedPin, AledRed);
analogWrite(AledGreenPin, AledGreen);
analogWrite(AledBluePin, AledBlue);
analogWrite(BledRedPin, BledRed);
analogWrite(BledGreenPin, BledGreen);
analogWrite(BledBluePin, BledBlue);
}
From the Arduino docs on readString:
Serial.readString() reads characters from the serial buffer into a string. The function terminates if it times out (see setTimeout()).
and the docs on setTimeout:
Serial.setTimeout() sets the maximum milliseconds to wait for serial data when using Serial.readBytesUntil(), Serial.readBytes(), Serial.parseInt() or Serial.parseFloat(). It defaults to 1000 milliseconds.
This means that the readString is always waiting 1 sec to make sure that the sending of the string is finished and has the complete string.
Unfortunately that means it's slow to respond. You could lower the timeout with the setTimeout, but you would still have some delay, or if you set it too low you could potentially get incomplete stings.
The best solution would be to use readStringUntil, so you know you have a complete string when you get a terminator character (like a newline).
Replace
Command = Serial.readString();
with
Command = Serial.readStringUntil('\n');
and make sure you set the Serial monitor so send the newline character.
Edit: see important update at the end.
This can be made significantly faster, but first let's have a look at the work that has to be done in every loop iteration with the current code:
As #gre_gor already explained, you could be losing some time in readString().
for each value, between 15 and 20 bytes have to be sent, read, parsed and converted to int.
for each received value (R, G or B), analogWrite() is called 6 times (and analogWrite() isn't really fast). This means that in order to change the two series, analogWrite() is called 36 times (and this is probably where most time is lost). And if no serial data is available, analogWrite() is still called 6 times.
and also, Serial.println() is called each time in the example - so it would be best to turn this off.
To speed this up, the RGB values could be sent in a small buffer (assuming you have control over the sending side as well), and read with Serial.readBytesUntil().
If the values for both A and B are sent together, the 6 RGB values can be sent as 6 bytes:
byte rcvBuffer[7];
void loop() {
if (Serial.available() > 0) {
// message: RGBRGBx - but see update below
int numRead = Serial.readBytesUntil(0x78, rcvBuffer, 7); // 0x78 is 'x'
if (numRead == 7) { // or 6, see below
analogWrite(AledRedPin, rcvBuffer[0]);
analogWrite(AledGreenPin, rcvBuffer[1]);
analogWrite(AledBluePin, rcvBuffer[2]);
analogWrite(BledRedPin, rcvBuffer[3]);
analogWrite(BledGreenPin, rcvBuffer[4]);
analogWrite(BledBluePin, rcvBuffer[5]);
}
// else ignore this read - could be a first unaligned read
}
}
If only the values for A or B are sent together:
byte rcvBuffer[5];
void loop() {
// You could probably even remove the Serial.available() check
if (Serial.available() > 0) {
// message: TRGBx where T is Type ('A' or 'B')
int numRead = Serial.readBytesUntil(0x78, rcvBuffer, 5); // 0x78 is 'x'
if (numRead == 5) { // or 4, see below
switch (rcvBuffer[0]) {
case 'A':
analogWrite(AledRedPin, rcvBuffer[1]);
analogWrite(AledGreenPin, rcvBuffer[2]);
analogWrite(AledBluePin, rcvBuffer[3]);
break;
case 'B':
analogWrite(BledRedPin, rcvBuffer[1]);
analogWrite(BledGreenPin, rcvBuffer[2]);
analogWrite(BledBluePin, rcvBuffer[3]);
break;
default :
// do nothing, or send error message
}
}
}
}
I used 'x' as the stop byte to make it visible, but you could as well use a zero byte.
Now, I'm not really sure if readBytesUntil() also reads the terminating byte into the buffer or skips it, and can't test this right now. But I would think only the RGB values are read into the buffer. In this case you'll have to change those values to the ones I put in the comments.
To save even more time, you could check each value and only call analogWrite() if that value did change since the last call (for each R, G and B).
Update: Obviously we can't just use 'x' or a zero byte as the stop byte, because each of the RGB values could also be an 'x' or zero byte (it's getting late here :). And while ReadBytes() could be used instead, it's better to have a stop byte to keep the buffers aligned. So I would suggest to use 0xff (255) as the stop byte and make sure none of the RGB values can be 0xff.
And just in case there could be other message types in the future, each message could also be prepended with a message code (1 or 2 bytes).
I always use readBytesUntil()whenever I use the serial port for communication.
It gets the job done, it always gets the entire string, but the same problem as readString()takes at least 1000ms to complete.
Using both Serial.setTimeout() and Serial.readBytesUntil() worked fine for me, by reducing the delay.
Something like:
Serial.setTimeout(250);
inData = Serial.readStringUntil('\n');

Detect pattern in incoming byte stream

I would like to detect a certain byte pattern in an incoming byte stream at the UART. I am using Arduino. Currently, the code detects a single \r character. On this character is detected, the byte stream before this character gets stored into a buffer. This is easy. This is my code;
int incomingByte = 0; // for incoming serial data
void setup() {
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}
void loop() {
// send data only when you receive data:
if (Serial.available() > 0 ) {
// read the incoming byte:
incomingByte = Serial.read();
if (incomingByte != '\r') {
buffer_incoming_data[index_buffer]=incomingByte;
index_buffer++;
} else {
index_buffer = 0;
}
}
}
Here is my problem. Instead of a single character \r, I would like to detect a byte pattern that looks like this 0xAA 0xBB 0xCC. When this byte pattern is detected, the byte stream before byte pattern gets stored into a buffer.
Guess you invoke loop() method inside real loop operator. I can suggest next way:
int incomingByte = 0; // for incoming serial data
int pattern [] = {0xAA, 0xBB, 0xCC};
int patternIndex = 0;
int patternSize = sizeof(pattern)/sizeof(pattern[0]);
void loop() {
// send data only when you receive data:
if (Serial.available() > 0 ) {
// read the incoming byte:
incomingByte = Serial.read();
if(pattern[patternIndex] != incomingByte){
// if we found begin of pattern but didn't reach the end of it
if(patternIndex>0){
for(int i=0; i<=patternIndex-1; i++){
buffer_incoming_data[index_buffer]=pattern[i];
index_buffer++;
}
}
patternIndex = 0;
}
if(pattern[patternIndex] == incomingByte){
patternIndex++;
}else{
buffer_incoming_data[index_buffer]=incomingByte;
index_buffer++;
}
//if we reached the end of pattern
if(patternIndex==patternSize){
//do something with buffer
patternIndex = 0;
index_buffer = 0;
}
}
}
As you can see, I didn't check index_buffer for "index out of range" exception, but you should. Hope I helped you.

Reading a character and integer command from radio in order to execute a function

I am trying to create a code and loop that can read a character and integer from radio. This character is a command that will represent a packet recover command. This code is being performed in Arduino. The purpose of this code is to read a character command and an integer number between 0 and 512. This integer value represents a number that corresponds to a packet. The data is stored using an EEPROM. I will comment in the code what I am trying to achieve.
Assuming some arbitrary data is already on the EEPROM.
//*******Functions to access EEPROM********//
void I2CEEPROM_Write( unsigned int address, byte data )
{
Wire.beginTransmission(EEPROM_ID);
Wire.write((int)highByte(address) );
Wire.write((int)lowByte(address) );
Wire.write(data);
Wire.endTransmission();
delay(5); // wait for the I2C EEPROM to complete the write cycle
}
byte I2CEEPROM_Read(unsigned int address )
{
byte data;
Wire.beginTransmission(EEPROM_ID);
Wire.write((int)highByte(address) );
Wire.write((int)lowByte(address) );
Wire.endTransmission();
Wire.requestFrom(EEPROM_ID,(byte)1);
while(Wire.available() == 0) // wait for data
;
data = Wire.read();
return data;
}
void sendPackets(uint32_t start, uint32_t ending, char message_type)
{
radio.begin(1200);
uint32_t starting=start;
int number_of_packets=ceil(((float)ending-start)/total_size);
uint32_t last_byte=start;
for (uint32_t j=starting; j<=start+(data_size*i)-1; j++)
{
if (j>ending-1)
break;
Serial.print("Address: ");
Serial.println(j);
Serial.print("Value :");
Serial.println(I2CEEPROM_Read(j));
last_byte=j;
}
starting=last_byte;
delay(100);
}
}
//*********Main Function******//
void setup()
{
Serial.begin(9600);
Serial.setTimeout(100); //don't wait longer than 100ms for incoming data
}
void loop(void)
{
char cmd;
int xyz;
if (Serial.available())
{
cmd = Serial.read();
// ***I don't know how the if statement will be structured inside the bracket*****//
if (cmd == 'C', xyz)
{
//**what do I write here such that I can find the packet number
relating to the integer (xyz). The integer is the packet number I am
looking for. The C command represents that I am trying to recover a
missing packet.**//
}
else if (cmd == 'S')
{
Serial.println("incomplete");
}
else if (cmd == 'V')
{
Serial.println("wrong");
}
else if (cmd == 'T')
{
Serial.println("correct");
}
else
{
Serial.println("retry");
}
}
}
If I understand you correctly, you are attempting to read in commands from Serial, and if you encounter the 'C' command, you expect an integer value (0-512) to follow. You will need to read the integer value in. Here's one way:
cmd = Serial.read();
if(cmd == 'C')
{
int packetNum = Serial.parseInt();
// Continue on with your packetNum
}
...
The Serial.parseInt() function will read in the ASCII-representation of numbers from the serial stream, and then it will attempt to parse them and return them as an integer value. The integer value is what you want to work with in your code.
But be warned: If Serial.parseInt() is unable to parse an integer value from the serial stream, or times out waiting for it, it will return the value 0. You can test for that return value and act on it accordingly, but in your case the value of 0 is also a legitimate packet number. If possible, you may want to change your allowable packet numbers to be 1-513 so you can easily handle this error condition. (There are other ways to go about it too, but this would be an easy fix).
For more information about Serial.parseInt(), see http://arduino.cc/en/Serial/ParseInt
Also, as an aside, instead of using a bunch of if/else if/else if branches for each possible argument, you might instead like to use a switch statement. It accomplishes the same thing, but makes the code cleaner and more elegant.
switch(cmd)
{
case 'C':
int packetNum = Serial.parseInt();
// Continue on with your packetNum
break;
case 'S':
Serial.println("incomplete");
break;
case 'V':
Serial.println("wrong");
break;
case 'T':
Serial.println("correct");
break;
default:
Serial.println("retry");
}
Learn about switch/case here: http://arduino.cc/en/Reference/SwitchCase

Resources