Pages: [1]   Go Down
Author Topic: how to convert output from ASCII byte to int?  (Read 1081 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 1
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
/*

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;
}
Logged

Grand Rapids, MI, USA
Offline Offline
Sr. Member
****
Karma: 6
Posts: 256
Yes, I remember
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
/* 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;
}
Logged

Offline Offline
Sr. Member
****
Karma: 19
Posts: 486
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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:
int humidity = 0;

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

Grand Rapids, MI, USA
Offline Offline
Sr. Member
****
Karma: 6
Posts: 256
Yes, I remember
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 508
Posts: 31416
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

I much prefer:-

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

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46042
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I much prefer:-
Can you explain why? The other seems more intuitive, to me.
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 508
Posts: 31416
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46042
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 508
Posts: 31416
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
But, I'd never think of doing it that way.
Well it goes to show we are all different.  smiley

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.
Logged

Dallas, TX USA
Offline Offline
Edison Member
*
Karma: 47
Posts: 2333
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Logged

Ontario
Offline Offline
God Member
*****
Karma: 20
Posts: 835
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 508
Posts: 31416
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Pages: [1]   Go Up
Jump to: