Hi everyone!
My code "work" but im sure it's bad implemented, so i'm asking for some help.
Explanation of the code:
I have to read by Hardware Serial port (TTL) a petition ">PTX<" where X could be any number from 0 to 9 (from a PIC in other PCB)
When I recieve one of those, I ask via Software serial port (with a conversor RS485 in between) to a Powermeter that answer in HEX float. So I "transform" those values in a String (now in ASCII) and return this (with some other parts "hardcoded" to keep it simple for now) to the PIC. Something like " >0,3,220.0,220.0,220.0,1,999# " Where "220.0" are the values I read from the Powermeter.
The problems that I found but don't know how to resolve are:
-The response to the PIC should be (or what I was trying to do) 3 Voltage in the first response, 3 Currents in 2nd. Power Factor, Hz and Energy in 3rd. In fact, the Energy is sended as the first value of the 1st response. changing the order of all others... >0,3,25.6,220.0,220.0,1,999# "
-If I Shutdown the Powermeter, the program keeps sending responses with the value of ENERGY in all the responses. for example :" >0,3,25.6,25.6,25.6,1,999# " Energy=25.6 for a bunch of times, an then all values goes to zero.
Sorry for my English, if there is somthing that isn't clear please tell me and i'll try to clarify.
#include <avr/wdt.h> //libreria de watchdog
#include <SoftwareSerial.h>
//#define enable485 4 //Pin enable RS485
// software serial: RX = digital pin 5, TX = digital pin 6
SoftwareSerial port485(5, 6);
///////////////////////// VARIABLES GLOBALES ///////////////////////////
const int tpo_reset = 300;
const int sensXmodulo = 3;
const int enable485 = 4;
int index = 0;
char trama[9]; //Datos desde SIMT
char respuesta[9]; //Datos desde Powermeter
int indice = 0;
String valores_trama; //Respuesta para SIMT
String pt100_trama; //Respuesta para SIMT
///////////////////TRAMAS DE PETICION POWERMETER///////////////////////
byte peticion[9][8] = {
{0x01, 0x03, 0x00, 0x09, 0x00, 0x02, 0x14, 0x09}, //0:Ua
{0x01, 0x03, 0x00, 0x0B, 0x00, 0x02, 0xB5, 0xC9}, //1:Ub
{0x01, 0x03, 0x00, 0x0D, 0x00, 0x02, 0x55, 0xC8}, //2:Uc
{0x01, 0x03, 0x00, 0x0F, 0x00, 0x02, 0xF4, 0x08}, //3.Ia
{0x01, 0x03, 0x00, 0x11, 0x00, 0x02, 0x94, 0x0E}, //4:Ib
{0x01, 0x03, 0x00, 0x13, 0x00, 0x02, 0x35, 0xCE}, //5:Ic
{0x01, 0x03, 0x00, 0x1B, 0x00, 0x02, 0xB4, 0x0C}, //6:fp
{0x01, 0x03, 0x00, 0x1D, 0x00, 0x02, 0x54, 0x0D}, //7:hz
{0x01, 0x03, 0x00, 0x21, 0x00, 0x02, 0x94, 0x01} //8:ea
};
char comandos[9][7] =
{
">PT0<",
">PT1<",
">PT2<",
">PT3<",
">PT4<",
">PT5<",
">PT6<",
">PT7<",
">PT8<"
};
void setup() {
wdt_disable();
pinMode(enable485, OUTPUT); //Configuro pin como salida
delay(50);
//Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) { }
delay(50);
port485.begin(9600); // Start software serial port
wdt_enable(WDTO_2S);
}
void(* resetFunc) (void) = 0; // funcion para reset
void loop() {
wdt_reset();
if(millis()/1000>tpo_reset){
resetFunc(); // Reset forzado
}
memset(trama, 0, sizeof(trama));
String strtrama = "";
while (Serial.available() > 0) {
char dato = Serial.read(); // Read a character
trama[index] = dato; // Store it
index++; // Increment where to write next
trama[index] = '\0'; // Null terminate the string
}
index = 0;
strtrama = trama;
delay(50); //Delay sino rompe todo
//Serial.print(" "); //DEBUG
Serial.flush(); //Clean serial port
delay(50);
for (int k = 0; k < 6 ; k++) {
if (strtrama == comandos[k]) { //Si es ">PTX<"
delay(20);
digitalWrite(enable485, HIGH); //RS485 como Transmisor
for (int t = 0; t < sensXmodulo ; t++) {
for (int i = 0; i < 8; i++) { //Envio trama de peticion a Powermeter
port485.write(peticion[k * 3 + t][i]);
}
digitalWrite(enable485, LOW); //RS485 como Receptor
while (port485.available() > 0) { //Leo puerto serie por software
char dato = port485.read();
respuesta[indice] = dato;
indice++;
respuesta[indice] = '\0';
}
indice = 0;
delay(20);
digitalWrite(enable485, HIGH); //RS485 como Transmisor
delay(20);
float data; //Variable auxiliar
union u_tag {
byte b[4];
float fval;
} u;
u.b[3] = respuesta[3]; //Guardo los bytes de interes
u.b[2] = respuesta[4]; //para interpretarlos como float.
u.b[1] = respuesta[5];
u.b[0] = respuesta[6];
data = u.fval;
char flotante[6];
dtostrf(data, 4, 1, flotante); //Convierto de Float a String
String flotanteStr = flotante;
flotanteStr.replace(" ", "");
valores_trama += flotanteStr;
valores_trama += ",";
}
String cabecera0 = ">";
String id = String(k);
String cabecera1 = ",3,";
String findetrama = "1,999#";
pt100_trama += cabecera0; //Armo trama de respuesta
pt100_trama += id;
pt100_trama += cabecera1;
pt100_trama += valores_trama; //para SIMT.
pt100_trama += findetrama;
delay(20);
port485.flush(); //Clean software serial port
delay(20);
Serial.print(pt100_trama); //Respuesta para SIMT
delay(20);
valores_trama = "";
pt100_trama = "";
}
}
}
I'm working in arduino nano.
Sorry about the languaje, I'll update the coments if something isn't clear.
Thanks in advance.