Go Down

Topic: Sodtwareserial problem. (Read 987 times) previous topic - next topic

Pavilion1984

Hello all, hop you can help me.

I have this bit of code

Code: [Select]
byte STN_transmit(char *str)
{
  while(*str != NULL)
  mySerial.write(*str++);
  }


and nothing is transmitted, just hangs on the line mySerial.write(*str++);. but if i use Serial.write it works fine. any ideas what is wrong here?

Thank you in advance.

Code: [Select]
///////////////////////////////
//Software serial port setup.//
///////////////////////////////
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); //Rx pin 2, Tx pin 3.
//////////////
//LCD setup.//
//////////////
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
#define COLUMNS 16
#define ROWS 2

#define NULL '\0'
///////////////////////////////////////
//STN AT cmd's.                      //
//Asterisk (*) marks default setting.//
///////////////////////////////////////
#define STN_D    "ATD\r"   //Set all settings to defaults.
#define STN_DPN  "ATDPN\r" //Describe current protocol by number.
#define STN_E0   "ATE0\r"  //Echo off.
#define STN_E1   "ATE1\r"  //Echo on*.
#define STN_L0   "ATL0\r"  //Linefeeds off*.
#define STN_L1   "ATL1\r"  //Linefeeds on.
#define STN_M0   "ATMO\r"  //Memory off.
#define STN_M1   "ATM1\r"  //Memory on*.
#define STN_RV   "ATRV\r"  //Read voltage.
#define STN_WS   "ATWS\r"  //Warm start.
#define STN_S0   "ATS0\r"  //Printing of spaces off.
#define STN_S1   "ATS1\r"  //Printing of spaces on*.
#define STN_SP0  "ATSP0\r" //Protocol - Automatic.
#define STN_SP1  "ATSP1\r" //Protocol - SAE J1850 PWM (41.6 kbaud).
#define STN_SP2  "ATSP2\r" //Protocol - SAE J1850 VPW (10.4 kbaud).
#define STN_SP3  "ATSP3\r" //Protocol - ISO 9141-2 (5 baud init, 10.4 kbaud).
#define STN_SP4  "ATSP4\r" //Protocol - ISO 14230-4 KWP (5 baud init, 10.4kbaud).
#define STN_SP5  "ATSP5\r" //Protocol - ISO 14230-4 KWP (fast init, 10.4 kbaud).
#define STN_SP6  "ATSP6\r" //Protocol - ISO 15765-4 CAN (11 bit ID, 500 kbaud).
#define STN_SP7  "ATSP7\r" //Protocol - ISO 15765-4 CAN (29 bit ID, 500 kbaud).
#define STN_SP8  "ATSP8\r" //Protocol - ISO 15765-4 CAN (11 bit ID, 250 kbaud).
#define STN_SP9  "ATSP9\r" //Protocol - ISO 15765-4 CAN (29 bit ID, 250 kbaud).
#define STN_Z    "ATZ\r"   //Reset device.
/////////////
//PID list.//
/////////////
#define CEL     0x04 //Calculated engine load value.
#define ECT     0x05 //Engine coolant temperature.
#define FP      0x0A //Fuel pressure.
#define ERPM    0x0C //Engine RPM.
#define VS      0x0D //Vehicle speed.
#define MAF     0x10 //MAF air flow rate.
#define TP      0x11 //Throttle position.
#define FLI     0x2F //Fuel Level Input.
#define AAT     0x46 //Ambient air temperature.
#define EOT     0x5C //Engine oil temperature.
#define EFR     0x5E //Engine fuel rate.
///////////////////////////////////////////////////
//Transmits ASCII encoded HEX data to the ELM IC.//
//For example 010C\r.                            //
///////////////////////////////////////////////////
byte STN_transmit(char *str)
{
  while(*str != NULL)
  mySerial.write(*str++);
}
////////////////////////////////////////////////////////
//Places a command into a string and then transmitted.//
////////////////////////////////////////////////////////
byte STN_cmd(char *str, char *cmd)
{
  sprintf(str, "%s", cmd);
  STN_transmit(str);
}
///////////////////////////////
//Reads data from the ELM IC.//
//For example 41 0C 7B 7B>.  //
///////////////////////////////
byte STN_read(char *str)
{
  int temp;
  byte i = 0;
 
  while((temp = mySerial.read()) != '>')
  {
    //Serial.println("a");
    if(temp >= ' ')
    str[i++] = temp;
    //if(i >= 16)
    //return 0; //Read is probably bad.
  }
  str[i] = NULL;
  //return 1; //Read is probably good.
}
/////////////////////////////////////////////////////////////////
//Checks the ELM response header against the transmited header.//
/////////////////////////////////////////////////////////////////
byte STN_response_header_check(char *str_rx, char *str_tx)
{
  if(str_rx[1] == str_tx[1] && str_rx[3] == str_tx[2] && str_rx[4] == str_tx[3])
  return 1; //Header check is good.
  else
  return 0; //Header check is bad.
}
/////////////////////////////////////////////////////////////
//Skips the header and converts the received string to HEX.//
//For example 7B 7B to 0x7B7B.                             //
/////////////////////////////////////////////////////////////
byte STN_compact_response(char *str_rx, byte *str_cr)
{
  byte i = 0;
 
  str_rx += 6;
 
  while(*str_rx != NULL)
  str_cr[i++] = strtoul(str_rx, &str_rx, 16);
}
//////////////////////////////////////////////////
//Initialize and setup the STN IC ready for use.//
//////////////////////////////////////////////////
void STN_initialize()
{
  char str[24];
 
  STN_cmd(str, "ATZ\r");
  STN_read(str);
  delay(1000);
  Serial.println(str);
 
  /*mySerial.print("ATM0\r");
  STN_read();
  delay(1000);
  Serial.println(str_rx);
 
  mySerial.print("ATSP0\r");
  STN_read();
  delay(1000);
  Serial.println(str_rx);*/
}
///////////////////////////////////////////////////////////
//Requests the PID and returns the calculated PID result.//
///////////////////////////////////////////////////////////
/*int get_PID(byte PID, char *str)
{
  char str_tx[16]; //String for ELM transmit data.
  char str_rx[16]; //String for ELM receive data.
  byte str_cr[16]; //String for compact response data.
  int temp;
 
  sprintf(str_tx, "01%02X\r", PID);
  elm_transmit(str_tx);
 
  if(elm_read(str_rx) == 0)
  {
    return sprintf(str, "RERR");
  }
 
  if(elm_response_header_check(str_rx, str_tx) == 0)
  {
    return sprintf(str, "HERR");
  }
 
  elm_compact_response(str_rx, str_cr);
 
  switch(PID)
  {
    case CEL:
    temp = (str_cr[0] * 100) / 255;
    break;
    case ECT:
    temp = str_cr[0] - 40;
    break;
    case FP:
    temp = str_cr[0] * 3;
    break;
    case ERPM:
    temp = ((str_cr[0] * 256) + str_cr[1]) / 4;
    break;
    case VS:
    temp = (str_cr[0] * 10000U) / 16090U;
    break;
    case TP:
    temp = (str_cr[0] * 100) / 255;
    break;
    case FLI:
    temp = (100 * str_cr[0]) / 255;
    break;
    case AAT:
    temp = str_cr[0] -40;
    break;
    case EOT:
    temp = str_cr[0] - 40;
    break;
    case EFR:
    temp =((str_cr[0] * 256) + str_cr[1]) * 0.05;
    break;
  }
  return temp;
}*/
//////////
//Setup.//
//////////
void setup()
{
  Serial.begin(9600); //Initialize the hardware serial port.
  mySerial.begin(9600); //Initialize the software serial port.
 
  lcd.begin(COLUMNS, ROWS); //Initialize LCD.
 
  STN_initialize();
}
/////////
//Main.//
/////////
void loop()
{
  char str[16];
  int temp;
 
  //temp = get_PID(ERPM, str);
  //sprintf(str, temp);
}
/*
int calculate_MPG()
{
  int temp_VS;
  int temp_EFR;
  int result;
 
  temp_VS = get_PID(VS);
  temp_EFR = get_PID(EFR);
 
  result = temp_VS * 4.546 / temp_EFR;
  return result;
}
*/

dxw00d

Bit of conflict here:
Code: [Select]
...
SoftwareSerial mySerial(2, 3); //Rx pin 2, Tx pin 3.
...
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
...

PaulS

Code: [Select]
byte STN_cmd(char *str, char *cmd)
{
  sprintf(str, "%s", cmd);
  STN_transmit(str);
}

What? It makes no sense whatsoever to copy cmd to str.

Code: [Select]
byte STN_transmit(char *str)
{
  while(*str != NULL)
  mySerial.write(*str++);
}

Why do you feel the need to write the string one character at a time? There are two versions of the write() method - one that writes a character and one that writes a string. Use the proper one to write a string.

Pavilion1984

I am new to software and know nothing about C so am still learning. What is the correct way then PaulS? Serial.print();?

PaulS

Quote
What is the correct way

Delete the STN_cmd() method. Replace any calls to the function with calls to STN_transmit().

In STN_transmit(),
Code: [Select]
byte STN_transmit(char *str)
{
  mySerial.write(str);
}

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy