Pages: [1]   Go Down
Author Topic: Some characters mismatch (PHP serial+LCD)  (Read 1730 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Spent lots of time, but still could not resolve this issue.

Let's assume I want to send a string from a PHP script to a 16x2 LCD connected to Arduino. The machine is running Windows XP.

I have a PHP script sending data:

Code:
<?php
require("php_serial_class.php"); //the one widely available on the Net

function writeToArduino($str)&#123;
      
      
$serial = new phpSerial();      
      
$serial->deviceSet("COM2");      
      
$serial->confBaudRate(9600);
      
      
$serial->deviceOpen();            
            for (
$i=0$i<strlen($str); $i++)&#123;
                  
$serial->sendMessage($str[$i]);
            &
#125;
                        
      
$serial->deviceClose();
      
      
&
#125;

$tmptext "12345ABCDE";
writeToArduino($tmptext);

?>

Arduino is simply getting it at immediately sends each read character on screen:
Code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup(){  
  lcd.begin(16, 2);  
  Serial.begin(9600);
  lcd.clear();
}

void loop(){
  char incomingByte = 0;      // for incoming serial data
         // send data as you receive it:
      if (Serial.available() > 0) {
            // read the incoming byte:
            incomingByte = Serial.read();            
            lcd.print(incomingByte);
      }

 }

And this is what I get as output:
(Sorry, I can't post the image here due to local forum restrictions. I'll try to post it in comments).
If I output data as int I can see that for some characters their ascii code is changed to "ascii code - 128", e.g. for "1" the corresponding code is displayed as -79 (49 - 128).
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is the output:
Logged

Left Coast, USA
Offline Offline
Sr. Member
****
Karma: 7
Posts: 499
Sometimes I just can't help myself.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
If I output data as int...
Try printing as unsigned.  Use HEX to make the bit patterns more obvious.

As I look at the data sheet for the '44780 controller here's what I observe from your worth-more-than-a-thousand-words picture:


ASCII   Binary of        Binary of
Char    ASCII Char       Displayed Char

'1'     0011 0001        1011 0001 (MSB is 1)
'2'     0011 0010        1011 0010 (MSB is 1)
'3'     0011 0011        0011 0011 (This is OK)
'4'     0011 0100        1011 0100 (MSB is 1)
'5'     0011 0101        1011 0101 (MSB is 1)
'A'     0100 0001        0100 0001 (OK I think: It's under the rubber band.)
'B'     0100 0010        0100 0010 (This is OK)
'C'     0100 0011        1100 0011 (MSB is 1)
'D'     0100 0100        0100 0100 (This is OK)
'E'     0100 0101        1100 0101 (MSB is 1)


It looks as if the port on your PC is set up for seven data bits + parity instead of eight bits, no parity.  (Since the MSB was set on chars whose ASCII values had odd parity, the MSB represents the parity bit that makes the whole eight bits have even parity.  That's what parity is all about.  Not what we need here, right? I mean, we absolutely, positively don't want to change the MSB from 0 to 1. Ever.)

Furthermore, some LCD communication bytes do need the MSB to be a '1'. In particular, the command that sets the display address when you perform a function call to set the cursor to a particular row and column has the MSB equal to 1.  So: Make sure your COM port is set to use eight data bits and no parity.  (But I said that already.)

Regards,

Dave
« Last Edit: July 15, 2010, 06:33:28 pm by davekw7x » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you for replies and explanations.
In order to avoid this problem I simply moved to Linux and everything works fine.
Logged

Devon, UK
Offline Offline
Full Member
***
Karma: 4
Posts: 234
Arduino rocks my socks, yes the socks are rocking!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Oh, this is easy, first off, use one int, you can afford it and it is easier, secondly, you have to take 48 away on the arduino side from the INT you receive.  Try this:

Code:
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup(){  
  lcd.begin(16, 2);  
  Serial.begin(9600);
  lcd.clear();
}

int incomingByte = 0;      // for incoming serial data
void loop(){

         // send data as you receive it:
      if (Serial.available() > 0) {
            // read the incoming byte:
            incomingByte = Serial.read();
            lcd.print(incomingByte - 48);
      }

 }
Logged

Poole, Dorset, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 29
Arduino is so cool it could stop global warming
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I had fun for this for a while. Then I cam across another similar topic and someone mentioned using PortMon to view the output to the serial port. In the log was a reference to 7 character encoding which appears to be the default for the php_serial.class library. The simple approach is to add:
      $serial->confCharacterLength(smiley-cool;
to your php script so it becomes:

<?php
require("php_serial.class.php"); //the one widely available on the Net

function writeToArduino($str){

      $serial = new phpSerial();
      $serial->deviceSet("COM2");
      $serial->confBaudRate(9600);
      $serial->confCharacterLength(smiley-cool;

      $serial->deviceOpen();
            for ($i=0; $i<strlen($str); $i++){
                  $serial->sendMessage($str[$i]);
            }

      $serial->deviceClose();


}

$tmptext = "12345ABCDE";
writeToArduino($tmptext);

?>
Logged

Pages: [1]   Go Up
Jump to: