I have an ARD 2560, which I communicate with through a special written Delphi 7 program (USB handling is done in the D-7 program).
I use the command syntax:
<REG> <COMMAND) <:> <NUMBER> <CR>
where
REG is A - K (the registers in the ARD 2650)
COMMAND can be a 2-chars command, but mostly 1-char commands.
EG: AR:255<cr> // AR configures DDRA to out- or in-put , depending on the parameter - (here 255 / 0xff) .
AI:0<cr> Read port A input (actually return content of ARD2560 port A input register)
AO:<number><CR> Send Number to port A (and return result to D-7 ).
......
All those command are valid for Reg A to Reg K.
The response time from transmit (d7) to I ("D/7") get the answer is approx. 1 1/2 second. I have a feeling that my code is a big, big kludge (it actually works), but I would like any advice(s) to to improve code // speeding it up.
If I drop the line:
if (char (pport[0] == '*' )) // '*' can be 'A' to 'K'
The response time increases to appr. 2 seconds.
(sorry that there are no comments!)
Here's the code:
#include <Esplora.h>
void setup()
{
Serial.begin(9600);
}
void loop()
{
String chr;
if (Serial.available() > 0)
{
String pport = Serial.readStringUntil(':');
{
String pos = Serial.readStringUntil('\n');
if (char (pport[0] == 'A' )) /* A */
{
if (pport == "AR")
{
DDRA = pos.toInt();
DOCRLF("//AR+", pos.toInt());
}
else
if (pport == "AI")
{
if (DDRA == B00000000)
{
Serial.print(PORTA);
chr = "//AI";
}
else
{
chr ="//AI-";
}
DOCRLF(chr , pos.toInt());
}
else
if (pport == "AO")
{
if (DDRA == B11111111)
{
PORTA = pos.toInt();
chr = "//AO+";
}
else
{
chr = "//AO-";
}
DOCRLF(chr, pos.toInt());
}
else
if (pport == "AU")
{
Serial.print(PORTA);
DOCRLF("//AU+", pos.toInt());
}
else
if (pport == "ABW")
{
PORTA = pos.toInt();
DOCRLF("//ABW+", pos.toInt());
}
else
if (pport == "ABR")
{
Serial.print(PORTA);
DOCRLF("//ABR+", pos.toInt());
}
}
else
if (char (pport[0] == 'B' )) /* B */
{
if (pport == "BR")
{
DDRB = pos.toInt();
DOCRLF("//BR+", pos.toInt());
}
else
if (pport == "BI")
{
if (DDRB == B00000000)
{
Serial.print(PORTB);
chr = "//BI+";
}
else
{
chr = "//BI-";
}
DOCRLF(chr, pos.toInt());
}
else
if (pport == "BO")
{
if (DDRB == B11111111)
{
PORTB = pos.toInt();
chr = "//BO+";
}
else
{
chr = "//BO-";
}
DOCRLF(chr, pos.toInt());
}
else
if (pport == "BU")
{
Serial.print(PORTB);
DOCRLF("//BU+", pos.toInt());
}
else
if (pport == "BBW")
{
PORTB = pos.toInt();
DOCRLF("//EBW+", pos.toInt());
}
else
if (pport == "BBR")
{
Serial.print(PORTB);
DOCRLF("//BBR+", pos.toInt());
}
}
else
if (char (pport[0] == 'C' )) /* C */
{
if (pport == "CR")
{
DDRC = pos.toInt();
DOCRLF("//CR+", pos.toInt());
}
else
if (pport == "CI")
{
if (DDRC == B00000000)
{
Serial.print(PORTC);
chr = "//CI+";
}
else
{
chr = "//CI-";
}
DOCRLF(chr, pos.toInt());
}
else
if (pport == "CO")
{
if (DDRC == B11111111)
{
PORTC = pos.toInt();
chr = "//CO+";
}
else
{
chr = "//CO-";
}
DOCRLF(chr, pos.toInt());
}
else
if (pport == "CU")
{
Serial.print(PORTC);
DOCRLF("//CU+", pos.toInt());
}
else
if (pport == "CBW")
{
PORTC = pos.toInt();
DOCRLF("//CBW+", pos.toInt());
}
else
if (pport == "CBR")
{
Serial.print(PORTC);
DOCRLF("//CBR+", pos.toInt());
}
}
else
if (char (pport[0] == 'D' )) /* D */
{
if (pport == "DR")
{
DDRD = pos.toInt();
DOCRLF("//DR+", pos.toInt());
}
else
if (pport == "DI")
{
if (DDRD == B00000000)
{
Serial.print(PORTD);
chr = "//DI+";
}
else
{
chr = "//DI-";
}
DOCRLF(chr, pos.toInt());
}
else
if (pport == "DO")
{
if (DDRD == B11111111)
{
PORTD = pos.toInt();
chr = "//DO+";
}
else
{
chr = "//DO-";
}
DOCRLF(chr, pos.toInt());
}
else
if (pport == "DU")
{
Serial.print(PORTD);
DOCRLF("//DU+", pos.toInt());
}
else
if (pport == "DBW")
{
PORTD = pos.toInt();
DOCRLF("//DBW+", pos.toInt());
}
else
if (pport == "DBR")
{
Serial.print(PORTE);
Serial.println("//DBR+");
}
}
else
if (char (pport[0] == 'E' )) /* E */
{
if (pport == "ER")
{
DDRE = pos.toInt();
DOCRLF("//ER+", pos.toInt());
}
else
if (pport == "EI")
{
if (DDRE == B00000000)
{
Serial.print(PORTE);
chr = "//ER+";
}
else
{
chr = "//ER-";
}
DOCRLF(chr, pos.toInt());
}
else
if (pport == "EO")
{
if (DDRE == B11111111)
{
PORTE = pos.toInt();
chr = "//EO+";
}
else
{
chr = "//EO-";
}
DOCRLF(chr, pos.toInt());
}
else
if (pport == "EU")
{
Serial.print(PORTE);
DOCRLF("//EU+", pos.toInt());
}
else
if (pport == "EBW")
{
PORTE = pos.toInt();
DOCRLF("//EBW+", pos.toInt());
}
else
if (pport == "EBR")
{
Serial.print(PORTE);
DOCRLF("//EBR+", pos.toInt());
}
}
else
if (char (pport[0] == 'F' )) /* F */
{
if (pport == "FR")
{
DDRF = pos.toInt();
DOCRLF("//FR+", pos.toInt());
}
else
if (pport == "FI")
{
if (DDRF == B00000000)
{
Serial.print(PORTF);
chr = "//FI+";
}
else
{
chr = "//F1-";
}
DOCRLF(chr, pos.toInt());
}
else
if (pport == "FO")
{
if (DDRF == B11111111)
{
PORTF = pos.toInt();
chr = "//FO+";
}
else
{
chr = "//FO-";
}
DOCRLF(chr, pos.toInt());
}
else
if (pport == "FU")
{
Serial.print(PORTF);
DOCRLF("//FU+", pos.toInt());
}
else
if (pport == "FBW")
{
PORTF = pos.toInt();
DOCRLF("//FBW+", pos.toInt());
}
else
if (pport == "FBR")
{
Serial.print(PORTF);
DOCRLF("//FBR+", pos.toInt());
}
}
else
if (char (pport[0] == 'G' )) /* G */
{
if (pport == "GR")
{
DDRG = pos.toInt();
DOCRLF("//GR+", pos.toInt());
}
else
if (pport == "GI")
{
if (DDRG == B00000000)
{
Serial.print(PORTG);
chr = "//GI+";
}
else
{
chr = "//GI-";
}
DOCRLF(chr, pos.toInt());
}
else
if (pport == "GO")
{
if (DDRG == B11111111)
{
PORTG = pos.toInt();
chr = "//GO+";
}
else
{
chr = "//GO-";
}
DOCRLF(chr, pos.toInt());
}
else
if (pport == "GU")
{
Serial.print(PORTG);
DOCRLF("//GU+", pos.toInt());
}
else
if (pport == "GBW")
{
PORTG = pos.toInt();
DOCRLF("//GBW+", pos.toInt());
}
else
if (pport == "GBR")
{
Serial.print(PORTG);
DOCRLF("//GBR+", pos.toInt());
}
}
else
if (char (pport[0] == 'H' )) /* H */
{
if (pport == "HR")
{
DDRH = pos.toInt();
DOCRLF("//HR+", pos.toInt());
}
else
if (pport == "HI")
{
if (DDRH == B00000000)
{
Serial.print(PORTH);
chr = "//HI+";
}
else
{
chr = "//HI-";
}
DOCRLF(chr, pos.toInt());
}
else
if (pport == "HO")
{
if (DDRH == B11111111)
{
PORTH = pos.toInt();
chr = "//HO+";
}
else
{
chr = "//HO-";
}
DOCRLF(chr, pos.toInt());
}
else
if (pport == "HU")
{
Serial.print(PORTH);
DOCRLF("//HU+", pos.toInt());
}
else
if (pport == "HBW")
{
PORTH = pos.toInt();
DOCRLF("//HBW+", pos.toInt());
}
else
if (pport == "HBR")
{
Serial.print(PORTH);
DOCRLF("//HBR+", pos.toInt());
}
}
else
if (pport == "RA")
{
int aport = (pos.toInt());
if (aport > -1 && aport < 16)
{
Serial.println (" OK ");
}
}
else
if (pport == "KO")
{
Serial.print("//KO+");
if (DDRA == B11111111)
{
Serial.print("A");
}
else
{
Serial.print("a");
}
if (DDRB == B11111111)
{
Serial.print("B");
}
else
{
Serial.print("b");
}
if (DDRC == B11111111)
{
Serial.print("C");
}
else
{
Serial.print("c");
}
if (DDRD == B11111111)
{
Serial.print("D");
}
else
{
Serial.print("d");
}
if (DDRE == B11111111)
{
Serial.print("E");
}
else
{
Serial.print("e");
}
if (DDRF == B11111111)
{
Serial.print("F");
}
else
{
Serial.print("f");
}
if (DDRG == B11111111)
{
Serial.print("G");
}
else
{
Serial.print("g");
}
if (DDRH == B11111111)
{
Serial.print("H");
}
else
{
Serial.print("h");
}
Serial.println();
}
}
}
}
void DOCRLF (String txt, int vval)
{
Serial.print(txt);
Serial.println(vval);
}
1 Answer 1
This is not really a proper answer to your question. As I mentioned in a comment, I believe your actual problem is the Delphi program not sending the LF character you sketch expects. Instead, I am giving here a coding style suggestion: do not repeat yourself.
Whenever you find yourself coding with copy-paste, you should try to
simplify the program using arrays and/or loops. Below is a suggested
alternative version of your loop()
, with most of its redundant
repetitive repetitions removed:
struct port_t {
volatile uint8_t *ddr;
volatile uint8_t *port;
};
static const port_t ports[] = {
{ &DDRA, &PORTA },
{ &DDRB, &PORTB },
{ &DDRC, &PORTC },
{ &DDRD, &PORTD },
{ &DDRE, &PORTE },
{ &DDRF, &PORTF },
{ &DDRG, &PORTG },
{ &DDRH, &PORTH },
{ NULL, NULL }, // there is no port I
{ &DDRJ, &PORTJ },
{ &DDRK, &PORTK },
{ &DDRL, &PORTL }
};
void loop()
{
// Read the command line.
if (Serial.available() == 0) return;
String pport = Serial.readStringUntil(':');
String pos = Serial.readStringUntil('\n');
// The "KO" command reads all ports.
if (pport == "KO") {
Serial.print("//KO+");
for (char port_id = 'A'; port_id <= 'H'; port_id++) {
if (*ports[port_id - 'A'].ddr == 0xff)
Serial.print(port_id);
else
Serial.print(tolower(port_id));
}
Serial.println();
return;
}
// Identify the port to act on.
char port_id = pport[0];
if (port_id < 'A' || port_id > 'L' || port_id == 'I') {
Serial.println(F("Error: unknown port."));
return;
}
port_t port = ports[port_id - 'A'];
// Perform the requested action.
String command = pport.substring(1);
String chr = String("//") + port_id + command;
if (command == "R") {
*port.ddr = pos.toInt();
DOCRLF(chr + "+", pos.toInt());
} else if (command == "I") {
if (*port.ddr == 0)
Serial.print(*port.port);
else
chr += "-";
DOCRLF(chr , pos.toInt());
} else if (command == "O") {
if (*port.ddr == 0xff) {
*port.port = pos.toInt();
chr += "+";
} else {
chr += "-";
}
DOCRLF(chr, pos.toInt());
} else if (command == "U" || command == "BR") {
Serial.print(*port.port);
DOCRLF(chr + "+", pos.toInt());
} else if (command == "BW") {
*port.port = pos.toInt();
DOCRLF(chr + "+", pos.toInt());
}
}
-
I wanna thank you. As a newbie to C (C++) in Arduino programming I wanted to do it in a way you just showed me. Using "ARRAYS" but I did not know how to. (A little easier in Delphi- I think ). ANyway I want to give you a very special "Thanks a lot" for 2 reasons. 1: You showed me at way to solve the problem and 2: by supplying a code example.Kristian Sander– Kristian Sander2018年03月14日 14:20:32 +00:00Commented Mar 14, 2018 at 14:20
-
@ Juraj: DARN - I need to update my basics. Thanks a lot for correcting (always thougt that '\n' == CR.) Now I'm wiser (a least a little !)Kristian Sander– Kristian Sander2018年03月14日 14:25:07 +00:00Commented Mar 14, 2018 at 14:25
-
I changed the '/n' to '\r' added LF to to the D-7 tx-routine (now transmits <str> + CRLF . That totally improved the speed on the old "KLUDGE"- version. Responsetime is no > 1.sec (I can' measure to be precise.) Added my "missing" rutines (void Setup() + DOCRLF(..) ) to the new version, compiled , corrected a typo , compiled again- and VOILA - it worked. Much faster than before - response time again far under 1 sec (unmeasured) . I am very ,very pleased. Thank you to both of you.Kristian Sander– Kristian Sander2018年03月14日 15:26:29 +00:00Commented Mar 14, 2018 at 15:26
-
@KristianSander, you can set faster baud rate. try 115200 baud or more2018年03月14日 19:18:50 +00:00Commented Mar 14, 2018 at 19:18
-
@Juraj: I will set the Baud-rate later, when the D-7 program is improved. There is a speed increase (opimizing code) there, too .Kristian Sander– Kristian Sander2018年03月18日 17:04:53 +00:00Commented Mar 18, 2018 at 17:04
readStringUntil('\n')
". Your problem looks to me like a timeout inreadStringUntil()
. Are you sure your Delphi program does send that LF character? And your serial port driver does not convert it to CR?