Go Down

Topic: Sodtwareserial problem. (Read 815 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