Go Down

Topic: int = char (Read 1 time) previous topic - next topic

g0tanks

I have the following piece of code:

Code: [Select]
char buffer[10];
itoa(336, buffer, 10);
int char4 = buffer[2];


Serial.println(buffer[2]) gives 6, which is correct. However Serial.println(char4) gives 54. Why? Is it because buffer[] is a char? If so, how can I convert it to int?

PaulS

Quote
However Serial.println(char4) gives 54. Why? Is it because buffer[] is a char?


Yes. You are printing the ascii value of the character, which is an int, so this:
Quote
If so, how can I convert it to int?

is a bit confusing.

If you know that each character in buffer represents a number, you can convert the ascii value to the number by subtracting '0' from it.

Code: [Select]
char threeChar = '3';
int threeInt = threeChar - '0';


The threeInt variable will now contain 3.

This:
Code: [Select]
char threeChar = 'Z';
int threeInt = threeChar - '0';

is valid code. It will compile, but it won't do anything useful.

You could test that buffer
  • contained a value between '0' and '9' before subtracting '0', if necessary.


OrlandoArias

The C standard says that int types must be at least 16 bit wide and char types must be 8 bit wide. In AVR architecture, the same applies. In your Arduino, an int type is 16 bits wide and a char type is 8 bits wide.

Unsigned char types (ASCII) will range from 00000000 (0) to 11111111 (255). Anything outside that range will yield incorrect results when passed to itoa() or any functions alike.

Quote
If you know that each character in buffer represents a number, you can convert the ascii value to the number by subtracting '0' from it.

This is a bad approach. It works for single characters only, but that is about it.
This is the proper approach.

AWOL

#4
Mar 20, 2010, 03:33 pm Last Edit: Mar 20, 2010, 03:34 pm by AWOL Reason: 1
Quote
This is a bad approach. It works for single characters only, but that is about it.


"bad" is quite strong word to use here.
IMHO, "atoi" may be ...shall we say, "inappropriate" too?

"sscanf" may be "good", but with a much larger footprint, than "atoi", whereas, assuming your own code is handling character input, "x - '0' " may be optimal in a microcontroller environment.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

PaulS

Quote
This is a bad approach. It works for single characters only, but that is about it.
This is the proper approach.


The OP did not ask how to convert buffer to an integer. OP asked how to convert buffer[2] to an integer. atoi is useless for converting anything other than properly NULL terminated strings to integers.

g0tanks

Thanks a lot, it works perfectly. However I now have another problem.

I wrote some code to use a 4-Digit 7-Segment display, incase anyone is wondering it looks like this:

Code: [Select]

// This is a code example for the 4-Digit 7-Segment Display from SparkFun

// digits
int d1 = 10;
int d2 = 11;
int d3 = 12;
int d4 = 13;

// segments
int sA = 0;
int sB = 1;
int sC = 2;
int sD = 3;
int sE = 4;
int sF = 5;
int sG = 6;

// number encodings
int n0[10] = {0, 0, 0, 0, 0, 0, 1};
int n1[10] = {1, 0, 0, 1, 1, 1, 1};
int n2[10] = {0, 0, 1, 0, 0, 1, 0};
int n3[10] = {0, 0, 0, 0, 1, 1, 0};
int n4[10] = {1, 0, 0, 1, 1, 0, 0};
int n5[10] = {0, 1, 0, 0, 1, 0, 0};
int n6[10] = {0, 1, 0, 0, 0, 0, 0};
int n7[10] = {0, 0, 0, 1, 1, 1, 1};
int n8[10] = {0, 0, 0, 0, 0, 0, 0};
int n9[10] = {0, 0, 0, 0, 1, 0, 0};

void setup()
{
 // pinmodes
 pinMode(sA, OUTPUT);
 pinMode(sB, OUTPUT);
 pinMode(sC, OUTPUT);
 pinMode(sD, OUTPUT);
 pinMode(sE, OUTPUT);
 pinMode(sF, OUTPUT);
 pinMode(sG, OUTPUT);

 pinMode(d1, OUTPUT);
 pinMode(d2, OUTPUT);
 pinMode(d3, OUTPUT);
 pinMode(d4, OUTPUT);
}

void loop()
{
 displayn();
}

void display(int digit, int number)
{
 int nArray[10];
 
 // turn on digit
 digitalWrite(digit, HIGH);
 
 // use correct number encoding array
 for (int a = 0; a < 11; a++) {
   switch (number) {
   case 0:
   nArray[a] = n0[a];
   break;
   case 1:
   nArray[a] = n1[a];
   break;
   case 2:
   nArray[a] = n2[a];
   break;
   case 3:
   nArray[a] = n3[a];      
   break;
   case 4:
   nArray[a] = n4[a];
   break;
   case 5:
   nArray[a] = n5[a];
   break;
   case 6:
   nArray[a] = n6[a];
   break;
   case 7:
   nArray[7] = n7[a];
   break;
   case 8:
   nArray[a] = n8[a];
   break;
   case 9:
   nArray[a] = n9[a];
   break;                
   }
 }
 
// set segments
 digitalWrite(sA, nArray[0]);
 digitalWrite(sB, nArray[1]);
 digitalWrite(sC, nArray[2]);
 digitalWrite(sD, nArray[3]);
 digitalWrite(sE, nArray[4]);
 digitalWrite(sF, nArray[5]);
 digitalWrite(sG, nArray[6]);
 
 delay(1);
 
// turn off digit
 digitalWrite(digit, LOW);
}

void displayn()
{
 int char1;
 int char2;
 int char3;
 int char4;
 
 char1 = 4;
 char2 = 3;
 char3 = 2;
 char4 = 1;

  display(d4, char4);
  display(d3, char3);
  display(d2, char2);
  display(d1, char1);
}


The code is supposed to show '1234', which it does. However when I add the following (without modifying anything):

Code: [Select]

char buffer[10]
itoa(444, buffer, 10);


The display still shows the numbers but it also starts blinking with a delay of around half a second.

Am I missing something? How does itoa mess up my display?

AWOL

#7
Mar 20, 2010, 05:25 pm Last Edit: Mar 20, 2010, 06:27 pm by AWOL Reason: 1
Not sure about your delay, but this is going to bite you on the ass.
Code: [Select]
nArray[7] = n7[a];


Code: [Select]
int n0[10] = {0, 0, 0, 0, 0, 0, 1};
int n1[10] = {1, 0, 0, 1, 1, 1, 1};
int n2[10] = {0, 0, 1, 0, 0, 1, 0};
int n3[10] = {0, 0, 0, 0, 1, 1, 0};
int n4[10] = {1, 0, 0, 1, 1, 0, 0};
int n5[10] = {0, 1, 0, 0, 1, 0, 0};
int n6[10] = {0, 1, 0, 0, 0, 0, 0};
int n7[10] = {0, 0, 0, 1, 1, 1, 1};
int n8[10] = {0, 0, 0, 0, 0, 0, 0};
int n9[10] = {0, 0, 0, 0, 1, 0, 0};


Three things here:
1) Why ten elements for a seven segment display?
2) Why "int"s?
3) Why not a 2d array (which would make your code a lot shorter and easier to debug)?

Are you really using pins 0 and 1 as outputs?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

g0tanks

For points 1 and 2, that's just bad coding on my part. I just wanted to get the display to work before working on the code. I did look at 2D array's but wasn't quite sure about how to use the.

I only touched my first Arduino this friday and i'm also new to programming so my code isn't that great.  :D

Also i'm not sure what you mean with 'using pins 0 and 1 as outputs'?

AWOL

Quote
Also i'm not sure what you mean with 'using pins 0 and 1 as outputs'?

Code: [Select]
 pinMode(sA, OUTPUT);
 pinMode(sB, OUTPUT);


sA = 0 and sB = 1, so it appears you're using the serial Tx and Rx as segment outputs.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

g0tanks

Correct, I assume that it's a bad thing to do then? It still doesn't explain why it stops working properly when I add itoa though. :(

AWOL

#11
Mar 20, 2010, 09:44 pm Last Edit: Mar 20, 2010, 09:49 pm by AWOL Reason: 1
Quote
It still doesn't explain why it stops working properly when I add itoa though


No, it doesn't, but you haven't shown how/where you added it.

I'm not keen on this either:
Code: [Select]
 int nArray[10];

 // turn on digit
 digitalWrite(digit, HIGH);

 // use correct number encoding array
 for (int a = 0; a < 11; a++) {


with 'a' going from 0 to 10, and being used to address a ten element array.

You really need to check indices and array sizes.

Maybe read up on "memcpy", or bit manipulation.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

g0tanks

#12
Mar 20, 2010, 09:48 pm Last Edit: Mar 20, 2010, 09:50 pm by g0tanks Reason: 1
Thanks for the help. I'll try and check all those things. :)

It doesn't really matter where I put it. I've tried to put it on different places in void loop & displayn but it will still cause problems.

Go Up