This eludes me so I need some direction.
I am trying to send numerical values to the Arduino, for example the number 123. The Serial.read() receives it as separate ASCII values of 49, 50, and 51.
How do I turn this back into a int value of 123?
This eludes me so I need some direction.
I am trying to send numerical values to the Arduino, for example the number 123. The Serial.read() receives it as separate ASCII values of 49, 50, and 51.
How do I turn this back into a int value of 123?
Do a search on this site for 'atoi' , that's a to (eye) , this question has cropped up before.
Thats what I need, but where do I find the lib stdlib.h?
On a Linux system it is part of the avr-libc package but I don't know about Windows.
Never mind, it is included.
yeah i'm working with a similar program.... sending values to another arduino and setting pwm accordingly
#include <math.h>
#include "Wire.h"
#include "WiiChuck.h"
//#include "nunchuck_funcs.h"
#define MAXANGLE 90
#define MINANGLE -90
WiiChuck chuck = WiiChuck();
int angleStart, currentAngle;
int tillerStart = 0;
double angle;
void setup() {
//nunchuck_init();
Serial.begin(1200);
chuck.begin();
chuck.update();
chuck.calibrateJoy();
}
void loop() {
delay(500);
chuck.update();
// Serial.print(",jx ");
Serial.print((int)chuck.readJoyX()*-1+100);
// Serial.print(",jy ");
Serial.println((int)chuck.readJoyY()*-1+100);
}
this program simply reads joystick x y on wii nunchuck controller, makes it positive, and adds 100 to each (so that it's always 6 characters long)
example output: 233230
I searched the forum for atoi and found this example program
#include <stdlib.h> // needed for [shighlight]atoi[/shighlight]
char buffer[4];
int received;
int ledPin = 9;
void setup()
{
Serial.begin(9600);
received = 0;
buffer[received] = '\0';
}
void loop()
{
if (Serial.available())
{
buffer[received++] = Serial.read();
buffer[received] = '\0';
if (received >= (sizeof(buffer)-1))
{
Serial.print(buffer);
int myInt = [shighlight]atoi[/shighlight](buffer);
analogWrite(ledPin, myInt);
received = 0;
}
}
} }
}
when i did syntax check i had error:
In function 'void loop()':
error: expected primary-expression before '[' token At global scope:
i don't have the library #include <stdlib.h>? where would i find this?
It compiles,
The issue is this line here,
int myInt = [shighlight]atoi[/shighlight](buffer);
Note the [ shighlight] and the [ /shighlight] these are inserted into the code block to Highlight the word you are searching for, "atoi", Take that out and get rid of the 2 extra }} at the bottom and it should compile.
The lib should already be there.
that's good because i read it and thought "what is that???
i'll try again and see what happens
could i get a pointer in the right direction?
i'm trying to send variables in one long serial message:
#include <math.h>
#include "Wire.h"
#include "WiiChuck.h"
//#include "nunchuck_funcs.h"
#define MAXANGLE 90
#define MINANGLE -90
WiiChuck chuck = WiiChuck();
int angleStart, currentAngle;
int tillerStart = 0;
double angle;
void setup() {
//nunchuck_init();
Serial.begin(57600);
chuck.begin();
chuck.update();
chuck.calibrateJoy();
}
void loop() {
delay(1000);
chuck.update();
//Serial.print((int)9);
// Serial.print(",jx ");
Serial.print((int)chuck.readJoyX()*-1+100);
// Serial.print(",jy ");
Serial.println((int)chuck.readJoyY()*-1+100);
}
this sends for example 222232 (222 = joyX, 232=joyY)
how would i isolate the variables and be able to work with them in the program below?
#include <stdlib.h> // needed for [shighlight]atoi[/shighlight]
char buffer[9];
int received;
void setup()
{
Serial.begin(57600);
received = 0;
buffer[received] = '\0';
Serial.print("setup");
}
void loop()
{
if (Serial.available())
{
buffer[received++] = Serial.read();
buffer[received] = '\0';
if (received >= (sizeof(buffer)-1))
{
int myInt = atoi(buffer);
Serial.println(buffer);
Serial.print("1: ");
Serial.println(myInt/10);
Serial.print("2: ");
Serial.println(myInt/100);
Serial.print("3: ");
Serial.println(myInt%10);
Serial.print("4: ");
Serial.println(myInt%100);
received = 0;
}
}
}
I only know enough to be dangerous, but I'll give it a go.
I assume you mean to send the data "222232" from one to the other?
Maybe something like this
#include <stdlib.h>
char X_buffer[3];
char Y_buffer[3];
int received;
int i=0;
int X_pos=0;
int Y_pos=0;
void setup()
{
Serial.begin(57600);
received = 0;
X_buffer[received] = '\0';
Y_buffer[received] = '\0';
Serial.print("setup");
}
void loop()
{
if (Serial.available())
{
// Get x cord
for(i=0; i<3; i++)
{
X_buffer[i] = Serial.read();
}
// Get y cord
for(i=0; i<3; i++)
{
Y_buffer[i] = Serial.read();
}
X_pos = atoi(X_buffer);
Y_pos = atoi(Y_buffer);
}
/*
Serial.println(buffer);
Serial.print("1: ");
Serial.println(myInt/10);
Serial.print("2: ");
Serial.println(myInt/100);
Serial.print("3: ");
Serial.println(myInt%10);
Serial.print("4: ");
Serial.println(myInt%100);
received = 0;
}
}*/
}
I've been manipulating and rewriting both programs to no avail. In the first program i used i just don't understand why the serial read is "232230", but after atoi it's some oddball negative number.
I tried using this program
#include <stdlib.h>
char X_buffer[3];
char Y_buffer[3];
int received;
int i=0;
int X_pos=0;
int Y_pos=0;
void setup()
{
Serial.begin(57600);
received = 0;
X_buffer[received] = '\0';
Y_buffer[received] = '\0';
Serial.println("setup");
}
void loop()
{
if (Serial.available())
{
// Get x cord
for(i=0; i<3; i++)
{
X_buffer[i] = Serial.read();
}
// Get y cord
for(i=0; i<3; i++)
{
Y_buffer[i] = Serial.read();
}
X_pos = atoi(X_buffer);
Y_pos = atoi(Y_buffer);
Serial.print("x:");
Serial.print(X_pos);
Serial.print("y:");
Serial.print(Y_pos);
Serial.println();
}
}
with output
setup
x:2y:0
x:32230y:30
x:2y:0
x:-32306y:30
x:2y:0
x:32230y:30
x:2y:0
x:32230y:30
correct output should have been "232230"
i'm sending the data by:
Serial.print((int)chuck.readJoyX()*-1+100); //make is positive and always 3 digits long
// Serial.print(",jy ");
Serial.print((int)chuck.readJoyY()*-1+100); //make is positive and always 3 digits long
i've tried taking out the (int) makes no difference. I'm sending it as integer ascii?
here's the original program output
setup
*232230*-29914*
*233230*-28914*
*232230*-29914*
*232230*-29914*
it's getting the right 232230... after atoi it's unusable
If anyone is having the same problems, or wondering if the noob will ever shutup: I found a very good example program from http://rob.faludi.com/itp/clock_decode_with_debug.pde
Here 'rob' is decoding a serial message the same way i wanted to
// this program decodes a clock string sent via XBee radio
// the end result is six integer variables that hold the current year, month, day, hour, minute and second
//
// the time string is in the following format:
// *20061003143227
// where the year is 2006, month is October, day is the 3rd, hour is 14 (2 p.m.), minute is 32 and second is 27
//
// by Rob Faludi
// http://www.faludi.com
////// DEBUG OUTPUT IS HANDY, BUT NOT NECESSARY FOR CLOCK DECODING ///////
#include <SoftwareSerial.h>
int rx=6, tx=7; // pins 6 and 7 will have a debug output
SoftwareSerial softSerial(rx, tx); // creates SoftwareSerial on pins 6 and 7
///////////////////////////////////////////////////////////////
int ledPin = 13;
int year;
byte month, day, hour, minute, second;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode (rx,INPUT);
pinMode (tx,OUTPUT);
// start up the serial connection with 9600-8-n-1-true (non-inverted):
Serial.begin(9600); // start hardware serial process
softSerial.begin(9600); // start software serial process
// blink the status LED
blinkLED(ledPin, 2, 200);
softSerial.println(); // do a linefeed on the debug port
delay(500);
softSerial.println("starting..."); // show startup on the debug port
setupXBee();
}
void loop() {
Serial.flush(); // clear the serial buffer before reading new data
char timeString[15]; // create a string to hold the time value when it's read
memset(timeString,'\0',15); // initialize that string to all NULL characters
boolean timeStringValid = false; // declare and initialize a variable to track whether the string has all valid characters
Serial.print("GET");
byte inByte = '\0'; // declare and initialize a byte to read in serial data
long startTime = millis();//makes the start time = to now
int timeout = 1000; // timeout after one second
while(millis() - startTime < timeout && inByte != '*') {
inByte = Serial.read(); // read data and wait for an asterisk character
}
if (inByte == '*') { // if we got the correct start character (instead of a timeout)
timeStringValid = true; // declare and initialize a variable to track whether the string has all valid characters
long startTime = millis();//makes the start time = to now
int timeout = 1000; // timeout after one second
while(millis() - startTime < timeout && Serial.available() < 14) {
; //wait for enough data to be available (14 characters of time string), while doing nothing else
}
for (int i=0; i < 14; i++) {
timeString[i] = Serial.read(); // reach each time string character into a character array
if(timeString[i] < '0' || timeString[i] > '9') {
timeStringValid = false; // if any character is bad then the whole string is bad
}
}
softSerial.print("Time: ");
softSerial.println(timeString);
}
if (timeStringValid == true) {
char yearString[5]; // create a string to hold the year part of the string
memset(yearString,'\0',5); // initialize that string to all NULL characters
strncpy( yearString, timeString, 4); // copy the first four characters of timeString into the year string
year = atoi(yearString); // convert ASCII year string to integer and store in the year integer variable
softSerial.print("Year: ");
softSerial.println(year, DEC);
char monthString[3]; // create a string to hold the month part of the string
memset(monthString,'\0',3); // initialize that string to all NULL characters
strncpy( monthString, timeString+4, 2); // skip four characters, then copy the next two of timeString into the month string
month = atoi(monthString); // convert ASCII month string to integer and store in the month integer variable
softSerial.print("Month: ");
softSerial.println(month, DEC);
char dayString[3];
memset(dayString,'\0',3);
strncpy( dayString, timeString+6, 2);
day = atoi(dayString);
softSerial.print("Day: ");
softSerial.println(day, DEC);
char hourString[3];
memset(hourString,'\0',3);
strncpy( hourString, timeString+8, 2);
hour = atoi(hourString);
softSerial.print("Hour: ");
softSerial.println(hour, DEC);
char minuteString[3];
memset(minuteString,'\0',3);
strncpy( minuteString, timeString+10, 2);
minute = atoi(minuteString);
softSerial.print("Minute: ");
softSerial.println(minute, DEC);
char secondString[3];
memset(secondString,'\0',3);
strncpy( secondString, timeString+12, 2);
second = atoi(secondString);
softSerial.print("Second: ");
softSerial.println(second, DEC);
}
softSerial.println(""); // print a blank line
delay(1000); // wait for a moment so that output is readable
}
void setupXBee() {
boolean success = false;
int ctr = 0;
while (success == false && ctr < 6) {
// an arbitrary byte to wake up the XBee
Serial.print("X");
delay(1100);
// put the XBee in command mode
Serial.print("+++");
delay(1100);
Serial.flush(); // clear the serial buffer before sending and reading new data
// set the PAN (personal area network) ID number
Serial.print("ATIDC,");
// set the MY (16 bit address)
Serial.print("MY1,");
// set the Destination High to 0x0
Serial.print("DH0,");
// set the Destination Low (16 bit address)
Serial.print("DL0,");
// exit command mode (note that we use Serial.printLN here to issue a linefeed that completes the command sequence)
Serial.println("CN");
if (checkFor("OK", 1000)) {
// if an OK was received then continue
// debugPrintln("setup done");
softSerial.println("setup done");
success = true;
}
else {
// debugPrintln("setup failed");
softSerial.println("setup failed");
success = false;
}
ctr++;
}
}
///////////////////////////////// UTILITY FUNCTIONS //////////////////////////////////////////
// this function checks for a specific response on the serial port
// it accepts a string to look for and a timeout in milliseconds
int checkFor(char* desiredResponse, int timeout) {
int result = 0;
int length = 40;
char incomingResponse[41];
memset(incomingResponse,0,length); // initialize all incomingResponse string positions to null
char inByte = NULL;
long startTime = millis();//makes the start time = to now
char* ptr_incomingResponse = incomingResponse;
// while we haven't timed out or gotten back the string that we are looking for
while (millis() - startTime < timeout && strstr(incomingResponse,desiredResponse) == NULL ) { //strstr compares strings
if (Serial.available() > 0) { // if there are any bytes waiting to be read
inByte = Serial.read(); // read one byte
if (incomingResponse > ptr_incomingResponse-length) { // if we haven't read in 80 characters yet
*ptr_incomingResponse = inByte; // put the byte into the current position in the string
ptr_incomingResponse++; // advance to the next position in the string
}
else {
//move the last char to be next to last, and so forth until we reach the end of the array.
for (int i = 0; i < length; i++) {
incomingResponse[i] = incomingResponse[i+1];
}
incomingResponse[length-1] = inByte; // put the byte into the current position in the string
}
}
}
softSerial.println(incomingResponse);
if (strstr(incomingResponse,desiredResponse) != NULL ) { // if the desired string is found
result = 1;
}
else {
result = 0;
}
return result;
}
// this function blinks the an LED light as many times as requested
void blinkLED(int targetPin, int numBlinks, int blinkRate) {
for (int i=0; i<numBlinks; i++) {
digitalWrite(targetPin, HIGH); // sets the LED on
delay(blinkRate); // waits for a blinkRate milliseconds
digitalWrite(targetPin, LOW); // sets the LED off
delay(blinkRate);
}
}
thank you rob for the excessive commenting
thefatmoop--
The reason that atoi is returning such unexpected numbers for you is that it returns an int, which in Arduino-land is 16-bits and limited to a maximum value of 32767. If you use atol, which uses long instead, that may improve things.
Mikal
thanks that does make sense and adds clarity
Mikal, I think you meant -32768 to 32767 for an int (or 0 - 65535 for an unsigned int).
-j
Yipes! What am I thinking..?! Sorry: fixed.
Thanks, j.
M
Hi,
I am also trying to connect two pc Arduino because I do not have outputs for connecting to the GLCD.
I need to send value from my nunchuck and temp sensor to another Arduino.
I've used the code here on the forum but what I can not handle is negative numbers.
I have negative numbers that I have to use in my other Arduino.
What I need is something like:
x = 50 or x = -50 can be positive or negative numbers
y = 50 or y = -50 can be positive or negative numbers and
temp = 25 or temp = -2
Desire is to send all this in a string such as for example
*- 50 79 25, all numbers can be a digit or more and could be negative.
or maybe something like this
*x=value y=value temp=value
Best regards (sorry my english)
I've used the code here on the forum but what I can not handle is negative numbers.
There have been more that 170, 000 posts. We could not begin to guess which of those posts contain the code you are using.
I have negative numbers that I have to use in my other Arduino.
If you have negative numbers, you must not be using an unsigned type. That is not, then, the source of your problem.
Desire is to send all this in a string such as for example
*- 50 79 25, all numbers can be a digit or more and could be negative.
or maybe something like this
*x=value y=value temp=value
Either format is almost trivially simple. Using Serial.print(), the value specified is output as a string.
May I respectfully suggest that you use a closing delimiter, too. Send something like:
<-50 79 25>
This makes it much easier to determine when all the data for a packet has been received, and allows some level of checking for completeness. For example, there are two spaces in the string, so if you read '<', a number, a space, a number, a space, a number, and '>', you could be reasonably certain that there was no data loss.
If you have trouble sending or receiving and parsing the data, post your code. We'll be happy to help you get it working.
Writing it all for you, though, is not something we really want to do.
Hi again,
Thanks for your reply
The code I'm using is from this thread that is from Rob
What I'm doing right now is that I send my data from the Serial Monitor. I am writing myself in the serial monitor window and see what happens.
I have not tried to send data from my other Arduino. First I want to be sure that it works to receive and then I'll try to send from the correct source (Arduino)
Here is the code I have used where I send 7 characters * 252525 and it works but if I send *- 5-5-5 that is three negative numbers it does not work. I will use more characters later, but must first solve the problem.
void loop(){ // run over and over again
Serial.flush(); // clear the serial buffer before reading new data
char timeString[7]; // create a string to hold the time value when it's read
memset(timeString,'\0',7); // initialize that string to all NULL characters
boolean timeStringValid = false; // declare and initialize a variable to track whether the string has all valid characters
//Serial.print("GET");
byte inByte = '\0'; // declare and initialize a byte to read in serial data
long startTime = millis();//makes the start time = to now
int timeout = 1000; // timeout after one second
while(millis() - startTime < timeout && inByte != '*') {
inByte = Serial.read(); // read data and wait for an asterisk character
}
if (inByte == '*') { // if we got the correct start character (instead of a timeout)
timeStringValid = true; // declare and initialize a variable to track whether the string has all valid characters
long startTime = millis();//makes the start time = to now
int timeout = 1000; // timeout after one second
while(millis() - startTime < timeout && Serial.available() < 6) {
; //wait for enough data to be available (14 characters of time string), while doing nothing else
}
for (int i=0; i < 6; i++) {
timeString[i] = Serial.read(); // reach each time string character into a character array
if(timeString[i] < '0' || timeString[i] > '9') {
timeStringValid = false; // if any character is bad then the whole string is bad
}
}
Serial.print("Results: ");
Serial.println(timeString);
}
if (timeStringValid == true) {
char yearString[3]; // create a string to hold the year part of the string
memset(yearString,'\0',3); // initialize that string to all NULL characters
strncpy( yearString, timeString, 2); // copy the first four characters of timeString into the year string
Serial.print("X: ");
Serial.println(yearString);
char monthString[3]; // create a string to hold the month part of the string
memset(monthString,'\0',3); // initialize that string to all NULL characters
strncpy( monthString, timeString+2, 2); // skip four characters, then copy the next two of timeString into the month string
Serial.print("Y: ");
Serial.println(monthString);
char dayString[3];
memset(dayString,'\0',3);
strncpy( dayString, timeString+4, 2);
Serial.print("Temp: ");
Serial.println(dayString);
}
Serial.println(""); // print a blank line
delay(100); // wait for a moment so that output is readable
}
You have this code:
if(timeString[i] < '0' || timeString[i] > '9') {
timeStringValid = false; // if any character is bad then the whole string is bad
When you send a '-' as part of the string, you are declaring that the whole string is invalid.
Try this:
if([glow]([/glow]timeString[i] < '0' || timeString[i] > '9'[glow]) &&
timeString[i] != '-')[/glow] {
timeStringValid = false; // if any character is bad then the whole string is bad