Help with serial communication.

I’m trying to do some serial comms between an arduino and a liquidware touchscreen. It should be essentially the same as connecting an arduino to an arduino.

The premise of these sketches is that the arduino picks up signals from various sensors via it’s ADC and sends these readings to the other device as ints. Should be simple, but I haven’t been able to get it to work.

I have read this and it was helpful: Antipasto Hardware Blog: Passing large values between the Arduino to the TouchShield

arduino code

//code for arduino to use with touchshield and other programs
//pulls data from sensors and reports it across serial based on a handshake

#include <AFSoftSerial.h>

#define rxPin 3
#define txPin 2

AFSoftSerial vSerial = AFSoftSerial(rxPin, txPin);

int rtsPin = 4;
int ctsPin = 5;

int xval = 4;
int yval = 5;
int zerogy = 512;
int zerogx = 512;

//int sprayTriggerPin = 11;
//int piezoTriggerPin = 9;

int t1pin = 2;
int t2pin = 3;
int tempPin = 1;
int boostPin = 0;

int boost;
int oilT;
int t1;
int t2;
int x;
int y;

  
void setup(){
  //setup connection to tsshield
  vSerial.begin(9600);
  zeroAccelerometer();
}

void zeroAccelerometer(){
  //zero the accelerometer on startup
  int tempreading = analogRead(yval);
  if ((tempreading < 800) && (tempreading > 200)){
    zerogy = tempreading;
  }
  else {
    zerogy = 512;
  }
  tempreading = analogRead(xval);
  if (true) { 
    zerogx = tempreading;
  }
  else {
    zerogx = 512;
  }
}

void loop (){
  //handshake to say clear to send
  while(vSerial.read() != 'U'){}
  //Serial.print('U');
  //listen for queries from tsshield
    //full pull
  char readS = vSerial.read();
    if (readS == 'F'){  
      boost = lookup_boost(analogRead(boostPin));
      oilT = lookup_oil_temp(analogRead(tempPin));
      t1 = lookup_temp(analogRead(t1pin));
      t2 = lookup_temp(t2pin);
      sendFloat(boost);
      sendFloat(oilT);
      sendFloat(t1);
      sendFloat(t2);
    }
    //xydisplay
    if (readS == 'X'){
      x = getAccelerometerData (xval);
      //y = getAccelerometerData (yval);  
      sendFloat(x);
      //sendFloat(y);
    }
    return;
}

void sendFloat(float sendVar){
  sendVar = sendVar * 10;
  int sendV = (int)sendVar;
  //TODO: change to using ints with * 10
  
  
  /*unsigned char lowByte, highByte;
  unsigned int val;
  //set val to something
  char firstByte = (unsigned char)val;
  char secondByte = (unsigned char)(val >> 8);
  char thirdByte = (unsigned char)(val >> 16);
  char fourthByte = (unsigned char)(val >> 24);
  vSerial.print(firstByte);
  delay(1);
  vSerial.print(secondByte);
  delay(1);
  vSerial.print(thirdByte);
  delay(1);
  vSerial.print(fourthByte);*/
  char lowByte = (unsigned char)sendV;
  char highByte = (unsigned char)(sendV >> 8);
  vSerial.print(highByte);
  delay(1);
  vSerial.print(lowByte);
  delay(10);
  //while(vSerial.read() != 'C'){} //check for clear signal before sending next
  return;
}

//correctly changed for float values
float lookup_boost(int boost){
  //boost = ( (boost-106000) / 259000 );
  // boost = ( (( boost * 398) / 1000) + 2); //2 is the y intercept
  //398 changed to 378 for slope...because slope was too steep
  boost = ( (( boost * 378) / 1000) - 4)/10; //get rid of the divide by ten when adding decimals on display
  return boost;
}

//code for defi/nippon-seiki temp sender  
float lookup_oil_temp(int tval){
  if (tval <= 200){
    return 0.0;
  }
  
  if (tval > 200 && tval <= 315){
    return .37 * tval + 47.74;
    //return (37 * tval + 4774);
  }
  
  if (tval > 315 && tval <= 477){
    return .28 * tval + 71.3;
    //return (28 * tval + 7130);
  }
  
  if (tval > 477 && tval <= 790){
    return .33 * tval + 35.59;
    //return (33 * tval + 3559);
  }
  
  if (tval > 790){
    return 999.9;
  } 
  
}


//correctly converted to float values
float lookup_temp(int tval){
  if (tval < 89){
   return (999.9); 
  }
  if (tval > 960){
    return (0.0);
  }
  if ((tval <= 960)&&(tval > 932)){
    return (((tval-1015.77))/(-1.72));
  }
  if ((tval <= 932)&&(tval > 896)){
    return (((tval-1042.01))/(-2.26));
  }
  if ((tval <= 896)&&(tval > 851)){
    return (((tval-1077.38))/(-2.80));
  }
  if ((tval <= 851)&&(tval > 791)){
    return (((tval-1122.64))/(-3.35));
  }
  if ((tval <= 791)&&(tval > 707)){
    return (((tval-1175.88))/(-3.88));
  }
  if ((tval <= 707)&&(tval > 624)){
    return (((tval-1214.41))/(-4.21));
  }
  if ((tval <= 624)&&(tval > 532)){
    return (((tval-1223.67))/(-4.28));
  }
  if ((tval <= 532)&&(tval > 437)){
    return (((tval-1186.51))/(-4.05));
  }
  if ((tval <= 437)&&(tval > 364)){
    return (((tval-1113.49))/(-3.66));
  }
  if ((tval <= 364)&&(tval > 306)){
    return (((tval-1022.32))/(-3.21));
  }
  if ((tval <= 306)&&(tval > 248)){
    return (((tval-90.78))/(-2.70));
  }
  if ((tval <= 248)&&(tval > 200)){
    return (((tval-785.75))/(-2.20));
  }
  if ((tval <= 200)&&(tval > 158)){
    return (((tval-665.07))/(-1.75));
  }
  if ((tval <= 158)&&(tval > 123)){
    return (((tval-553.00))/(-1.37));
  }
  if ((tval <= 123)&&(tval > 90)){
    return (((tval-417.52))/(-.94));
  }
}

//correctly converted to use float values
float getAccelerometerData (int axis){
  int zerog = 512;
  if (axis == 4){
   zerog = zerogx; 
  }  
  if (axis == 5){
   zerog = zerogy;
  }
 
  int rc = analogRead(axis);
  int top =( (zerog - rc) ) ; 
  float frtrn = ((float)top/(float)158);  //158Vint jumps are 1g for the ADXL213AE (original accel)
  //154Vint jumps are 1g for the ADXL322 (updated one)
  return frtrn;
}

/COLOR mwhite ={255,255,255};
COLOR mblack ={1,1,1};
/

//simple sketch to check sensor functionality

float boost = 0;
float oilT = 0;
float temp1 = 0;
float temp2 = 0;
float accely = 0;
float accelx = 0;

POINT m_point;

void setup (){

//communications with arduino basics
Serial.begin(9600);

//canvas stuff
//beginCanvas();
background(0,0,0);
stroke(255,255,255);
fill(255,255,255);
}

void loop() {
background(0,0,0); //blank the screen black
//labels
text(“meter demo”, 100, 5);
text(" boost pressure: ", 18, 18);
text("oil temperature: “, 18, 38);
text(” temperature 1: “, 18, 58);
text(” temperature 2: ", 18, 78);
text("accelerometer x: ", 18, 98);
/lcd_puts(" boost pressure: ", 18, 18, mwhite, mblack);
lcd_puts("oil temperature: “, 18, 38, mwhite, mblack);
lcd_puts(” tempearture 1: “, 18, 58, mwhite, mblack);
lcd_puts(” temperature 2: ", 18, 78, mwhite, mblack);
lcd_puts("accelerometer x: ", 18, 98, mwhite, mblack);
/

while (!(touch_get_cursor(&m_point))){
Serial.print(‘U’); //handshake
//while (Serial.read() != ‘U’){}
Serial.print(‘F’); //request for data block
boost = getAValue();
oilT = getAValue();
temp1 = getAValue();
temp2 = getAValue();
Serial.print(‘U’); //handshake
//while (Serial.read() != ‘U’){}
Serial.print(‘X’); //request a data block
accelx = getAValue();
//display data here
text((float)boost, 100, 18);
text((float)oilT, 100, 38);
text((float)temp1, 100, 58);
text((float)temp2, 100, 78);
text((float)accelx, 100, 98);

/* char out[7];
fmtDouble((double)boost, 2, out, 7);
lcd_puts(out, 100, 18, mwhite, mblack);
fmtDouble((double)oilT, 2, out, 7);
lcd_puts(out, 100, 38, mwhite, mblack);
fmtDouble((double)temp1, 2, out, 7);
lcd_puts(out, 100, 58, mwhite, mblack);
fmtDouble((double)temp2, 2, out, 7);
lcd_puts(out, 100, 78, mwhite, mblack);
fmtDouble((double)accelx, 2, out, 7);
lcd_puts(out, 100, 98, mwhite, mblack);
*/
delay(100); //delay so things are readable
}
while (touch_get_cursor(&m_point)){}
background(0,0,0);
bmp_draw(“mockbig”,0,0);

//wait until screen is touched
while(!touch_get_cursor(&m_point)){}
while(touch_get_cursor(&m_point)){}
}

float getAValue(){
int getValue = Serial.read();
getValue = (getValue << 8) + Serial.read();
float getValueF = (float)getValue / 10;
//Serial.print(‘C’);
delay(10);
return getValueF;
}
/*
//code from: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1207226548/11#11
//*************
void fmtDouble(double val, byte precision, char *buf, unsigned bufLen = 0xffff);
unsigned fmtUnsigned(unsigned long val, char *buf, unsigned bufLen = 0xffff, byte width = 0);

//
// Produce a formatted string in a buffer corresponding to the value provided.
// If the ‘width’ parameter is non-zero, the value will be padded with leading
// zeroes to achieve the specified width. The number of characters added to
// the buffer (not including the null termination) is returned.
//
unsigned
fmtUnsigned(unsigned long val, char *buf, unsigned bufLen, byte width)
{
if (!buf || !bufLen)
return(0);

// produce the digit string (backwards in the digit buffer)
char dbuf[10];
unsigned idx = 0;
while (idx < sizeof(dbuf))
{
dbuf[idx++] = (val % 10) + ‘0’;
if ((val /= 10) == 0)
break;
}

// copy the optional leading zeroes and digits to the target buffer
unsigned len = 0;
byte padding = (width > idx) ? width - idx : 0;
char c = ‘0’;
while ((–bufLen > 0) && (idx || padding))
{
if (padding)
padding–;
else
c = dbuf[–idx];
*buf++ = c;
len++;
}

// add the null termination
*buf = ‘\0’;
return(len);
}
//
// Format a floating point value with number of decimal places.
// The ‘precision’ parameter is a number from 0 to 6 indicating the desired decimal places.
// The ‘buf’ parameter points to a buffer to receive the formatted string. This must be
// sufficiently large to contain the resulting string. The buffer’s length may be
// optionally specified. If it is given, the maximum length of the generated string
// will be one less than the specified value.
//
// example: fmtDouble(3.1415, 2, buf); // produces 3.14 (two decimal places)
//
void
fmtDouble(double val, byte precision, char *buf, unsigned bufLen)
{
if (!buf || !bufLen)
return;

// limit the precision to the maximum allowed value
const byte maxPrecision = 6;
if (precision > maxPrecision)
precision = maxPrecision;

if (–bufLen > 0)
{
// check for a negative value
if (val < 0.0)
{
val = -val;
*buf = ‘-’;
bufLen–;
}

// compute the rounding factor and fractional multiplier
double roundingFactor = 0.5;
unsigned long mult = 1;
for (byte i = 0; i < precision; i++)
{
roundingFactor /= 10.0;
mult *= 10;
}

if (bufLen > 0)
{
// apply the rounding factor
val += roundingFactor;

// add the integral portion to the buffer
unsigned len = fmtUnsigned((unsigned long)val, buf, bufLen);
buf += len;
bufLen -= len;
}

// handle the fractional portion
if ((precision > 0) && (bufLen > 0))
{
*buf++ = ‘.’;
if (–bufLen > 0)
buf += fmtUnsigned((unsigned long)((val - (unsigned long)val) * mult), buf, bufLen, precision);
}
}

// null-terminate the string
*buf = ‘\0’;
} */

sti,

On the Arduino side of things, the available() routine has worked well for me in the past because I noticed that it’s easy to get out of sync.

I guess you could get around this by using a KISS style serial packet framing, but it’s not really needed here.

So maybe something like,

char inChar;

loop()
{

inChar = 0;

if( vSerial.available() )
{
inChar = vSerial.read();
}

//look at inChar for meaningful data…
}

Dang, you are everywhere. Do you ever sleep? ;D

Thanks for the suggestion.

When I get some free time I'll try this method and if that doesn't work I'll work from your pin visualizer code

Ok, I still can’t figure this out. I simplified things and tried to pull a single value using the technique outlined in the blog. It still doesn’t work and I’m stumped.

Arduino code:

//code for arduino to use with touchshield and other programs
//pulls data from sensors and reports it across serial based on a handshake

#include <AFSoftSerial.h>

#define rxPin 3
#define txPin 2

AFSoftSerial vSerial = AFSoftSerial(rxPin, txPin);

int rtsPin = 4;
int ctsPin = 5;

int xval = 4;
int yval = 5;
int zerogy = 512;
int zerogx = 512;

//int sprayTriggerPin = 11;
//int piezoTriggerPin = 9;

int t1pin = 2;
int t2pin = 3;
int tempPin = 1;
int boostPin = 0;

float boost;
float oilT;
float t1;
float t2;
float x;
float y;

  
void setup(){
  //setup connection to tsshield
  vSerial.begin(9600);
  while(vSerial.read() != 'U'){}
  zeroAccelerometer();
}

void zeroAccelerometer(){
  //zero the accelerometer on startup
  int tempreading = analogRead(yval);
  if ((tempreading < 800) && (tempreading > 200)){
    zerogy = tempreading;
  }
  else {
    zerogy = 512;
  }
  tempreading = analogRead(xval);
  if (true) { 
    zerogx = tempreading;
  }
  else {
    zerogx = 512;
  }
}

void loop (){
  //listen for queries from tsshield
    //full pull
  char readS = vSerial.read();
    //xydisplay
    if (readS == 'X'){
      //x = getAccelerometerData(xval);
      //y = getAccelerometerData(yval);  
      x = analogRead(xval);
      //y = analogRead(yval);
      sendVariable(x);
      //sendVariable(y);
    }
    return;
}

void sendVariable(int sendVar){
  unsigned int sendV = (unsigned int)sendVar;
  unsigned char lowByte = (unsigned char)sendV;
  unsigned char highByte = (unsigned char)(sendV >> 8);
  vSerial.print(highByte);
  delay(1);
  vSerial.print(lowByte);
  delay(1);
  return;
}

float getAccelerometerData (int axis){
  int zerog = 512;
  if (axis == 4){
   zerog = zerogx; 
  }  
  if (axis == 5){
   zerog = zerogy;
  }
 
  int rc = analogRead(axis);
  int top =( (zerog - rc) ) ; 
  float frtrn = ((float)top/(float)158);  //158Vint jumps are 1g for the ADXL213AE (original accel)
  //154Vint jumps are 1g for the ADXL322 (updated one)
  return frtrn;
}

Touchshield code:

//simple sketch to check and display accelerometer data


float accelx = 0;
float accely = 0;
POINT m_point;

void setup (){
  //communications with arduino basics
  Serial.begin(9600); 
  delay(3000);
  Serial.print('U');
  //canvas stuff
  //beginCanvas();
  background(0,0,0); 
  stroke(255,255,255);
  fill(255,255,255); 
}

void loop() {
  background(0,0,0); //blank the screen black
  while (!(touch_get_cursor(&m_point))){
    Serial.print('X'); //request for data block
    text("x: ", 2, 2);
    text("y: ", 2, 10);
    int x = getAValue();
    int y = 0; // getAValue();
    text(x, 15, 2);
    text(y, 15, 10);
    if (x > 512){x = 160 + x/3;}
    else {x = 160 - x/3;}
    if (y > 512) {y = 120 + y/4;}
    else {y = 120 - y/4;}
    //point(x, y);
    ellipse(x, y, 2, 2);
    delay(500); //delay so things are readable
  }
  while (touch_get_cursor(&m_point)){}  
}

int getAValue(){
  //while(Serial.available()){}
  int getValue = Serial.read();
  getValue = (getValue << 8) + Serial.read();
  //Serial.print('C');
  delay(20);
  //while(Serial.read()!='C'){}
  return getValue;
}