11 years, 5 months ago.

Serial communication between 2 mbeds and displaying data to the KS0108 GLCD.

Hello!,

For the past few days i have been attempting to send a sensor data from one mbed to another. I am using 2 kl25z's and i am trying to send an integer value. I have looked at a lot of threads and sorted out a lot of issues.

The issue that i am facing is:

1- The transmitter is sending the integer and the receiver is receiving the integer. The data is printed to the pc serial monitor correctly. 2- The integer is printed to the serial monitor correctly, but on the display i get values like 10,50,52,54,56 etc.

This is the transmitter program:

  1. include "mbed.h"

Serial micro(PTD3, PTD2);
Serial pc(USBTX,USBRX);

int num=2;

int main()
{
while (1) {
        num=num*2;
        if(micro.writeable())
        {        
         micro.printf("%d",num);
         wait(5);
        }
    }    
}          

This is the receiver program:

#include "mbed.h"
#include "KS0108.h"        

Serial pc(USBTX, USBRX);
Serial micro(PTD3, PTD2); // tx, rx
        
KS0108 display (PTC7, PTD4, PTA12, PTA4, PTE0, PTE1, PTC8, PTC9, PTA13, PTD5, PTD0, PTC12, PTA16, PTA17);                        
void testlib(int i);

int num;

int main() 
{
     while(1) 
     {
      if(micro.readable()) 
      {
            num=(micro.getc());
            pc.putc(num);
            display.PrintInteger(num,3,0);
       }
    }       
 }    

Serial monitor prints the correct value 4,8,16,32,64 etc without spaces. I was hoping to print the same on the display. I was hoping someone could help me solve this issue. Thank you for your help!

1 Answer

11 years, 5 months ago.

The problem is you are sending it as ASCII, and getc reads it as character, so the ascii code behind it. And you print that value. If you check an ascii table then you can verify that.

Now solutions depend on what you want to do exactly. You can use putc(num) on the send side, then you send it binary, and can handle number up to 255. Or add a space/newline (\n) on the send side, and then use micro.scanf("%d", &num) on the receive side. That reads the incoming string and converts it to decimal.

Accepted Answer

Just for completeness, you can send a larger numbers as binary. The basic method is:

void sendInt( int numberToSend ) {

  char *dataStart = (char *) &numberToSend;
  for (int i = 0; i < sizeof(int); i++) {
    serialPort.putc( *(dataStart + i) );
  }

}


int getInt() {

 int numberIn;

 char *dataStart = (char *)&numberIn;
 char byteIn;

 for (int i = 0; i < sizeof(int); i++) {
    byteIn = serialPort.getc()
     *(dataStart + i) = byteIn;
 }

 return numberIn;
}

binary has the advantage that you send less data and the amount is more predictable (always 2 bytes for a 16 bit number Vs between 2 and 7 bytes for the same number as text). The other advantage in binary is that text needs a lot more code space and CPU time, printf and scanf require the stdio library which on some of the smaller mbed parts takes a fair chunk of the flash space, they are also fairly complex functions that take a reasonable amount of CPU time to run. Binary on the other hand is a lot smaller and faster in terms of code you need to run.

On the other hand binary has a big downside that it's harder to debug problems because the data isn't human readable and if the two ends of the link get out of synchronization for any reason (an unreliable link, one end expects an int but is sent a char etc...) they will stay that way until you either start again or add extra checks to the data to prevent it (e.g. prefix everything with a data size and/or data start flags and/or add checksums to the data). With text the new line characters act as a means to keep things in sync, if you do miss something then it'll get back in sync on the next line.

Generally unless you need the speed/size advantages of binary it's best to stick to sending text but they both have their place.

(edited to fix syntax errors in code)

posted by Andy A 29 Apr 2014

Thanks a ton, Erik! It worked. I still have one small problem. I hope you can help me solve it. The thing is that i am using an Arduino UNO instead of a hall effect sensor to generate wheel speed signal(pulses). The signal is given to one of the KL25Zs and using interrupts the KL25Z (No.1) is able to measure the speed.

Once the speed is measured the board No.1 uses a shift register to light up 8 leds based on the rpm. As the RPM increases, more number of leds light up. Once this is done the Board no.1 sends the rpm serially to the 2nd KL25Z. The second kl25z sends the data serially to the pc and also prints the rpm on the ks0108 display. The first board reads the rpm correctly, but the second board sometimes misses one digit. Hence 10,080 is read as 1008. How can i reduce the data loss? Will using binary reduce the chance of losing data.

PS. Most of the times the data is read correctly, but at times one or more digits are missed.

posted by Vishwaprashanth Kumar 29 Apr 2014

It might be due to the code you use for reading now, could you post it?. Is it always the same decimal that is gone?

posted by Erik - 29 Apr 2014