Go Down

Topic: int to char trouble (Read 985 times) previous topic - next topic

TomK

I am working with a max7219 that controls a 5x7 led matrix with the pattern library i found here;http://www.stefanomanni.it/arduino/wp-content/uploads/2009/03/text-scrolling-with-a-5c3977-led-matrix.zip
It is a library of patterns called in the arduino code to scroll letter numbers etc.
I am also using the DHT22 temp and humidity sensor with its own library to get readings.

I want to scroll these reading on the led matrix but have run into a problem.
the function to scroll text uses a string of declared characters to call each pattern. this is fine when scrolling text,
Code: [Select]
scrollString("TEXT")
but not if i want to scroll the reading from the sensor,
Code: [Select]
scrollString(myDHT22.getTemperatureC())
i end up with invalid conversion from int to char

is there any way i could get the sensor readings to work with this pattern library?
here is my code
Code: [Select]

/* 29 mar 09 */
/* Text scrolling with a 5x7 led matrix.
/* ATTENTION: Copy Pattern.h file in ./hardware/libraries/Pattern/ directory */
#include <DHT22.h>
#include <avr/pgmspace.h>
#include <Pattern.h>
#define DHT22_PIN 7

#define DELAY 75
// Setup a DHT22 instance
DHT22 myDHT22(DHT22_PIN);

int dataIn = 2;
int load = 4;
int clock = 3;

int matrix[7][5]={{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},};

int e = 0;     // just a varialble

// define max7219 registers
byte max7219_reg_noop        = 0x00;
byte max7219_reg_digit0      = 0x01;
byte max7219_reg_digit1      = 0x02;
byte max7219_reg_digit2      = 0x03;
byte max7219_reg_digit3      = 0x04;
byte max7219_reg_digit4      = 0x05;
byte max7219_reg_digit5      = 0x06;
byte max7219_reg_digit6      = 0x07;
byte max7219_reg_digit7      = 0x08;
byte max7219_reg_decodeMode  = 0x09;
byte max7219_reg_intensity   = 0x0a;
byte max7219_reg_scanLimit   = 0x0b;
byte max7219_reg_shutdown    = 0x0c;
byte max7219_reg_displayTest = 0x0f;

void putByte(byte data) {
  byte i = 8;
  byte mask;
  while(i > 0) {
    mask = 0x01 << (i - 1);      // get bitmask
    digitalWrite( clock, LOW);   // tick
    if (data & mask){            // choose bit
      digitalWrite(dataIn, HIGH);// send 1
    }else{
      digitalWrite(dataIn, LOW); // send 0
    }
    digitalWrite(clock, HIGH);   // tock
    --i;                         // move to lesser bit
  }
}


void sendToMax( byte reg, byte value) {   
  digitalWrite(load, LOW);       // begin     
  putByte(reg);                  // specify register
  putByte(value);
  digitalWrite(load, LOW);       // and load da shit
  digitalWrite(load,HIGH);
}


void setup () {
  //wired up to max7219
  pinMode(dataIn, OUTPUT);
  pinMode(clock,  OUTPUT);
  pinMode(load,   OUTPUT);
 
  //initiation of the max 7219
  sendToMax(max7219_reg_decodeMode, 0x00);  // not using  digits
  sendToMax(max7219_reg_scanLimit, 0x06); //scan rows 1 2 3 4 5 6 7
  sendToMax(max7219_reg_shutdown, 0x01);    // not in shutdown mode
  sendToMax(max7219_reg_displayTest, 0x00); // no display test
  sendToMax(max7219_reg_intensity, 0xf);     // range: 0x00 to 0x0f
 
  for (e=1; e<=7; e++) {    // empty registers, turn all LEDs off
  sendToMax(e,0);
  }


//I don't know why pow function doesn't work correctly.
//So i prefer to write my personal version of this.
int power(int base, int ex){
int i=1;
int tot=1;
if(i==0) return(1);
else{
      while(i<=ex){
      tot=tot*base;
      i++;
      }
      return(tot);
}
}

void lightOn(){
int i,j,k;

   //light on matrix
     for(i=0;i<7;i++){
     k=0;
     for(j=0;j<5;j++){
   
     if(matrix[i][j]==1) k=k+power(2,j);
     }
     sendToMax(i+1,k);
     }
}


 
void scrollChar(const int pattern[7][5]){

    int i,j,k=0;

while(k<5)    //column of pattern
{
    //shift rigidly columns from right to left
    for(j=0;j<4;j++){  //column
      for(i=0;i<7;i++){  //row
      matrix[i][j]= matrix[i][j+1];
    }
    }
   
    //queue k-th column of pattern
    for(i=0;i<7;i++){  //row
       matrix[i][4]=pgm_read_byte(&((pattern)[i][k]));     
    }
   
    lightOn();
    delay(DELAY);   
    k++;   
}//end while

insertSpace();
}


//insert a space (two column filled with zeros) beetween two chars
void insertSpace(){
int i,j,k=0;

while(k<2)    //queue two column of zero
{
    //shift rigidly columns from right to left
    for(j=0;j<4;j++){  //column
      for(i=0;i<7;i++){  //row
      matrix[i][j]= matrix[i][j+1];
    }
    }
   
    //queue two column filled with zeros
    for(i=0;i<7;i++){  //row
       matrix[i][4]=0;     
    }
   
    lightOn();
    delay(DELAY);   
    k++;   
}//end while
}


void scrollString(char * s){
int i=0;
   while (s[i])
  { 
    //symbols and letters
   
    if(s[i]=='*')
      scrollChar(PATTERN_ELLIP);
    if(s[i]=='.')
      scrollChar(PATTERN_PERIOD);
    if(s[i]=='=')
      scrollChar(PATTERN_HEART);
    if(s[i]=='!')
      scrollChar(PATTERN_EXCLAMATION);
    if(s[i]=='%')
      scrollChar(PATTERN_PERCENT);
    if(s[i]==' ')
      scrollChar(PATTERN_BLANK);
    if(s[i]=='A')
      scrollChar(PATTERN_A);
    if(s[i]=='B')
      scrollChar(PATTERN_B);
    if(s[i]=='C')
      scrollChar(PATTERN_C);
    if(s[i]=='D')
      scrollChar(PATTERN_D);
    if(s[i]=='E')
      scrollChar(PATTERN_E);
    if(s[i]=='F')
      scrollChar(PATTERN_F);
    if(s[i]=='G')
      scrollChar(PATTERN_G);
    if(s[i]=='H')
      scrollChar(PATTERN_H);
    if(s[i]=='I')
      scrollChar(PATTERN_I);
    if(s[i]=='J')
      scrollChar(PATTERN_J);
    if(s[i]=='K')
      scrollChar(PATTERN_K);
    if(s[i]=='L')
      scrollChar(PATTERN_L);
    if(s[i]=='M')
      scrollChar(PATTERN_M);
    if(s[i]=='N')
      scrollChar(PATTERN_N);
    if(s[i]=='O')
      scrollChar(PATTERN_O);
    if(s[i]=='P')
      scrollChar(PATTERN_P);
    if(s[i]=='Q')
      scrollChar(PATTERN_Q);
    if(s[i]=='R')
      scrollChar(PATTERN_R);
    if(s[i]=='S')
      scrollChar(PATTERN_S);
    if(s[i]=='T')
      scrollChar(PATTERN_T);
    if(s[i]=='U')
      scrollChar(PATTERN_U);
    if(s[i]=='V')
      scrollChar(PATTERN_V);
    if(s[i]=='W')
      scrollChar(PATTERN_W);
    if(s[i]=='X')
      scrollChar(PATTERN_X);
    if(s[i]=='Y')
      scrollChar(PATTERN_Y);
    if(s[i]=='Z')
      scrollChar(PATTERN_Z);
   
    //numbers
    if(s[i]=='1')
      scrollChar(PATTERN_1);
    if(s[i]=='2')
      scrollChar(PATTERN_2);
    if(s[i]=='3')
      scrollChar(PATTERN_3);
    if(s[i]=='4')
      scrollChar(PATTERN_4);
    if(s[i]=='5')
      scrollChar(PATTERN_5);
    if(s[i]=='6')
      scrollChar(PATTERN_6);
    if(s[i]=='7')
      scrollChar(PATTERN_7);
    if(s[i]=='8')
      scrollChar(PATTERN_8);
    if(s[i]=='9')
      scrollChar(PATTERN_9);
    if(s[i]=='0')
      scrollChar(PATTERN_0);

i++;
}//end while

}


void loop () {

  DHT22_ERROR_t errorCode;   // in this loop, the sensor gets readings
                             // and ideally plugs them into the scroll function
  delay(5000);

  errorCode = myDHT22.readData();
  switch(errorCode)
  {
    case DHT_ERROR_NONE:
      scrollString("TEMP : ");
      delay(500)
      scrollString(myDHT22.getTemperatureC())
      delay(500)
      scrollString("F ");
      delay(500)
      scrollString("HUMID : ");
      delay(500)
      scrollString(myDHT22.getHumidity());
      delay(500)
      scrollString("%");
      break;       
    case DHT_ERROR_TOOQUICK:
      scrollString("TOO QUICK ");
      break;
    case DHT_ERROR_NOT_PRESENT:
      scrollString("NOT PRESENT");
      break;
  }

Nick Gammon

Look up sprintf. You need to convert the int to a string, something along these lines:

Code: [Select]
int reading = myDHT22.getTemperatureC();
char buf [20];
sprintf (buf, "%i", reading);
scrollString (buf);
http://www.gammon.com.au/electronics

PaulS

The itoa() function can convert an int to an array of characters, too, but without any control over the format of the resulting array of characters (similar to %d), at a fraction of the overhead of sprintf, if memory is a problem.

TomK

thank you for the quick responses. i am out of town and away from my arduino and matrix but the code compiles fine and looks like it should do the trick.
thanks
tom

TomK

sprintf works perfectly. thank you!

Nick Gammon


The itoa() function can convert an int to an array of characters, too, but without any control over the format of the resulting array of characters (similar to %d), at a fraction of the overhead of sprintf, if memory is a problem.


Indeed, a quick test shows that using sprintf takes 1368 more bytes of program than using itoa. So if you are down to your last 1500 bytes or so, and have no other reason to use sprintf, then itoa might save the day. Example:

Code: [Select]
int reading = myDHT22.getTemperatureC();
char buf [20];
itoa (reading, buf, 10);


With itoa you can specify a base too (eg. base 10 as in the example, or base 16 for hex).

In both cases you need to make sure the buffer is long enough to hold the converted number.
http://www.gammon.com.au/electronics

TomK

i am now using itoa and like you said i am saving about 1500 bytes. this is great because i plan to add a rtc which will also use the itoa conversion so i will need that saved space.
thanks

Nick Gammon

That's great! Between us we got things going and saved you some space.

I should point out though that you don't use the 1500 bytes every time you call sprintf. Only calling it once causes its code to be incorporated in your sketch. After that, subsequent uses are "free".
http://www.gammon.com.au/electronics

TomK

Ohhhhhh I see. So the first time I call sprintf, or some other function, it gets written to the memory, then each time I call it again it just refers back to that memory?
At least now I have more space for the rtc code and anything else I may incorporate.

Nick Gammon

Sort of. When you use a function the linker includes it as part of your program code. So the more things you use the larger the program gets (plus the stuff you write yourself).
http://www.gammon.com.au/electronics

Go Up