Go Down

Topic: how to convert output from ASCII byte to int? (Read 1 time) previous topic - next topic

laiii

I m passing the data from the sensor from arduino to MAX MSP. However, MAX seems reading the data in ASCII format.

Like here, from the humidity sensor, if the result from the environment is 40(%), then in MAX, is reading in ASCII dec => 52 (means character 4) 48 (means charter 0).

To control and display data in MAX, I will need the real integer. Anyone knows how to convert it?


Million Thanks!!



my code:

Code: [Select]
/*

Example of BH1750 library usage.

This example initalises the BH1750 object using the default
high resolution mode and then makes a light level reading every second.

Connection:
VCC-5v
GND-GND
SCL-SCL(analog pin 5)
SDA-SDA(analog pin 4)
ADD-NC or GND

*/

#include <Wire.h>
#include <BH1750.h>


BH1750 lightMeter;

#define dht_dpin 12
byte bGlobalErr;
byte dht_dat[5];

void setup(){
InitDHT();
Serial.begin(9600);
delay(100);

lightMeter.begin();

//Serial.println("Humidity and temperature/n/n");
delay(1000);
}
void loop(){

uint16_t lux = lightMeter.readLightLevel();
int sensorValue = digitalRead(12);
int sensorValue2 = analogRead(A5);

Serial.write(sensorValue);
Serial.write(sensorValue2);
ReadDHT();
switch (bGlobalErr){
    case 0:

//if (40<=sensorValue && sensorValue<=127){
Serial.print(dht_dat[0]);//humidity
//Serial.print("%,"); can add if u want to use the number of comma to separate data
Serial.print("\n");
Serial.print(dht_dat[2]);//temperature in c
Serial.print("\n");
Serial.print(lux);
//Serial.print("light\n");

       break;
    case 1:
       Serial.println("Error 1: DHT start condition 1 not met.");
       break;
    case 2:
       Serial.println("Error 2: DHT start condition 2 not met.");
       break;
    case 3:
       Serial.println("Error 3: DHT checksum error.");
       break;
    default:
       Serial.println("Error: Unrecognized code encountered.");
       break;
     }

//}
delay(800);
}
void InitDHT(){
  pinMode(dht_dpin,OUTPUT);
       digitalWrite(dht_dpin,HIGH);
}
void ReadDHT(){
bGlobalErr=0;
byte dht_in;
byte i;
digitalWrite(dht_dpin,LOW);
delay(20);
digitalWrite(dht_dpin,HIGH);
delayMicroseconds(40);
pinMode(dht_dpin,INPUT);
//delayMicroseconds(40);
dht_in=digitalRead(dht_dpin);
if(dht_in){
  bGlobalErr=1;
  return;
  }
delayMicroseconds(80);
dht_in=digitalRead(dht_dpin);
if(!dht_in){
  bGlobalErr=2;
  return;
  }
delayMicroseconds(80);
for (i=0; i<5; i++)
  dht_dat[i] = read_dht_dat();
pinMode(dht_dpin,OUTPUT);
digitalWrite(dht_dpin,HIGH);
byte dht_check_sum =
      dht_dat[0]+dht_dat[1]+dht_dat[2]+dht_dat[3];
if(dht_dat[4]!= dht_check_sum)
  {bGlobalErr=3;}
};



byte read_dht_dat(){
byte i = 0;
byte result=0;
for(i=0; i< 8; i++){
     while(digitalRead(dht_dpin)==LOW);
     delayMicroseconds(30);
     if (digitalRead(dht_dpin)==HIGH)
    result |=(1<<(7-i));
   while (digitalRead(dht_dpin)==HIGH);
   }
return result;
}

jroorda

Do a little bit of looking at the C atoi() function.  This function is part of the standard C language and it can be used to convert an array (your ASCII output needs to be placed in a char array) to an integer.  The example code below is just generic C code and will not run on an Arduino, but it should help you see how to use it.  If my memory serves me right you will need to include the stdlib library as is done below.

Code: [Select]
/* atoi example */
#include <stdio.h>      /* printf, fgets */
#include <stdlib.h>     /* atoi */

int main ()
{
  int i;
  char buffer[256];
  printf ("Enter a number: ");
  fgets (buffer, 256, stdin);
  i = atoi (buffer);
  printf ("The value entered is %d. Its double is %d.\n",i,i*2);
  return 0;
}


TanHadron

It's not too hard to convert ASCII to int.  The hardest thing is knowing how long the number is.  It looks like you have 4 digits and a checksum.  If you only want the first two digits, it's really easy:

Code: [Select]

int humidity = (dht_dat[0] - '0') * 10 + dht_dat[1] - '0';


if it's 4 digits long, and there are leading zeros, you can do it in a loop:

Code: [Select]

int humidity = 0;

  for (byte i = 0; i < 4; ++i)
    humidity = humidity * 10 + dht_dat[i] - '0';

jroorda

I don't know why subtracting '0' has never occurred to me, but that is a much more elegant solution for short numbers.  If this seams like black magic, google yourself up an ASCII chart.

Grumpy_Mike

Code: [Select]
humidity = humidity * 10 + dht_dat[i] - '0';

I much prefer:-

Code: [Select]
humidity = humidity * 10 + dht_dat[i]  & 0xf;

PaulS

Quote
I much prefer:-

Can you explain why? The other seems more intuitive, to me.

Grumpy_Mike


Quote
I much prefer:-

Can you explain why? The other seems more intuitive, to me.

Well it is the way I see things, as bit patterns.

In a computer all things are bit patterns and we put meaning on those patterns according to context. So you have the ASCII code where, for numeric characters the bottom four bits are actually the binary representation of that number. Therefore ANDing with 0xf simply removes the top bits and leaves me with the bits I want.

Put it down to my hardware background but I see this as easier than than subtracting two things that are both abstractions in themselves. I prefer one operation with a numeric mask to transform it into one of the fundamental abstractions of a bit pattern which is a binary weighted number.

PaulS

Quote
Well it is the way I see things, as bit patterns.

In a computer all things are bit patterns and we put meaning on those patterns according to context. So you have the ASCII code where, for numeric characters the bottom four bits are actually the binary representation of that number. Therefore ANDing with 0xf simply removes the top bits and leaves me with the bits I want.

Put it down to my hardware background but I see this as easier than than subtracting two things that are both abstractions in themselves. I prefer one operation with a numeric mask to transform it into one of the fundamental abstractions of a bit pattern which is a binary weighted number.

OK. Thanks for the explanation. I hadn't ever paid attention to the fact that " for numeric characters the bottom four bits are actually the binary representation of that number". Given that, what you're doing makes sense.

But, I'd never think of doing it that way. I see the character '4' and know that if I subtract '0' from it, I'll get 4. The same as if I see 'H', and know that if I subtract 'A' and then subtract 1, I'll get the position of the letter in the alphabet. Useful for hashing, for instance.

Grumpy_Mike

Quote
But, I'd never think of doing it that way.

Well it goes to show we are all different.  :)

I am not daft enough to think there is only one "right way"

As my Dad used to say " there is more than one way of killing a pig than strangling it with butter "
Mind you no one knows why he said that.

bperrybap

I always use the standard atoi() and ctype functions because they always work.
While things like subtracting things like '0' or ANDing or ORing bits tend to work fine
on ASCII, there are cases were the same operations don't work on other character sets.

I had to fix lots of broken code back in the early eighties when porting  unix
to ibm 370 platforms which use ebcidic.
There was code that tried to short cut using ctype functions like toupper(), isupper(), tolower() etc...
by doing their own inline range comparisons.
That kind of stuff doesn't work with EBCIDIC since the letters are not sequential.

For Arduino not such a big deal but when doing larger things that might be using other character
sets, it can come back to haunt you and sometimes the issues can be quite subtle or difficult to track down.

--- bill


gardner


I much prefer:-


Hmm.  Not with you on that.  The two approaches take the same number of instructions, so not much to choose between them efficiency-wise.  But subtracting '0' makes it more obvious what is going on.  Also "& 0x0f" relies on a stronger assumption: digits are sequential AND the low four bits are the digit values.  Subtracting '0' only relies on the first, weaker, assumption.

Grumpy_Mike


Subtracting '0' only relies on the first, weaker, assumption.

That is your assumption it is not mine. In my mind that is the weaker assumption and rather abstract.

Go Up