Hello,
I'm hoping to use an arduino to act as a translator between two different pieces of equipment. I have the complete command and communication protocols for both so I know what it would receive and what it should output going in both directions and there's only ~20 different strings it would have to translate.. Does anyone have any experience with this or a project I could use as a reference?
Thank you!
The first thing anyone will want to see is a pointer to the two protocols, because the devil is in the details. Otherwise, sure, someone could cobble together a tool that matches strings for you; would likely prove to be utterly useless.
By the way, welcome! You'll find this community is very technical, and detail-driven, so be prepared to answer lots of detailed questions. There's not much tolerance for those who ignore same.
For your project, I'd recommend an Arduino with at least three hardware serial ports, by the way.
You'll want one for each device, and Serial Monitor is an excellent debugging tool, so use it. For what you want to do, don't go down the 'software serial' rabbit hole, and don't try to do without Serial Monitor.
This may help:
Thanks for your reply. I can try to be a bit more specific. The commands are all no more than 20 characters and they all have identical functions but the baud rate is different for the two things. For example:
The control unit will output "ch1 enable\n" at 9600 and wait for the reply "done\n". The unit I want it to control is expecting "on c1\r" at 115200 and will reply with "done\r".
The problem is I'd like to avoid linking to the exact docs since this is a way of skirting around buying a whole new control unit and I doubt the company would be too happy to find out. Thanks for the advice, I'll look into serial monitor.
That might make some reluctant to help, also. Especially if this is in any kind of critical system where safety was involve.
But in the abstract it seems like a simple enough problem.
Are you aware of any hard timing or timing out issues?
Perhaps you could disguise the commands and responses and present here a similar set of the traffic you expect, being sure to include anything out of the ordinary, that is to say at least one example of every kind of message you would expect to receive or need to generate.
And give some maximums that would need to be handled, like how many and of what lengths.
On the other hand, we very good at keeping secrets. I really don't think you'd have a problem just saying what it actually consists in and pointers to some real documents. ![]()
a7
Do either of the protocols use error checking and recovery?
FWIW, without the specs, this has all the hallmarks of an 80-100 post rabbit hole, so I'm checking out. Good luck, I wish you well.
I am not an attorney but some maintenance and warranty and licensing legal matters may rely upon the equipment owner/operator not attempting to interface with purchased/owned machinery. You are considering "spoofing" which may be considered by some as "hacking."
Be cautious as the U.S. laws are not very clear on owner rights and is in fact are being reframed but "repair" != "command/control spoofing"
Right to repair movement gains power in US and Europe - BBC News
Hacking a equipment interface may fall under laws that are meant to prevent such activity ... even if the commands for operation are published for documentation.
IF all you are doing is changing to a faster baud rate, then just do a 1 for 1 transfer. Read a byte and write a byte.
Ah, it's nothing so sinister. It's just companies trying to force you to buy their own equipment. They make all of the docs completely open and they expect people to be writing their own control programs in LabVIEW and interfacing with other equipment. They just like to make it really difficult to interface with equipment from other companies. Don't worry, no laws are being broken, I just don't want to lose friends in a very niche field.
Then speed/protocol/ 1::1 translation is fairly straight-forward; key engineering issue is to minimize delta-t of in transit comms as ACK/NAK is likely not part of the original stream.
- Avoid delay() at all cost
- Keep loop() simple
- Assemble characters in real-time, avoid Strings
- Exercise care using pointers into character strings stored in flash as there is and extra processor step to retrieve them and move to SRAM
- Avoid using buffer-then-parse as too many cpu cycles required
Snipplet of real-time serial character-by-character identification:
// not complete code base
[GPS_NoLib.ino|attachment](upload://dBFQACbYv4gFJK52YxZLlcBKAuj.ino) (6.4 KB)
char buffer[9];
char nmea[120];
char UART_UartGetChar() {
char i = '\0';
return i;
}
void loop(void)
{
if (Flag == 1)
{
GLCD_WRITE("Waiting on GPS") ;
// Flag = 0;
c = UART_UartGetChar(); // Get received character or null
if (c)
{
if(c == '$') // $ start of NMEA sentences
{
for(k=0; k<5; k++) // need 5 characters for sentence type
{
LED_Write( ~LED_Read() ); // flicker LED for activity
do {
c = UART_UartGetChar();
}
while (! (c));
nmea[k] = c; // G + P + R + M + C
// sprintf(buffer + k, "%c", c) ; // only for debug
}
LED_Write( LOW ); // LED off
if (strstr(nmea, "GPRMC"))
{
do {
do {
c = UART_UartGetChar();
LED_Write( ~LED_Read() ); // flicker LED
} while (!(c));
nmea[k] = c;
++k;
} while ( !( c == '*' ) && k < 120) ; // marker
LED_Write( LOW ); // LED off
// Inspiration: Limor Fried's Arduino GPS lib
char *p = nmea;
p = strchr(p, ',') + 1; // position after 1st comma
// float timef = atof(p);
// uint32_t time = timef;
uint32_t time = atoi(p);
hour = time / 10000;
minute = (time % 10000) / 100;
seconds = (time % 100);
// output to GLCD
sprintf(buffer, " %s",""); // clearbuffer
Essentially a state-machine. Concept extension is complicated by adding more strings to identify; but you will need to likely sync your code on CR or LF, not both.
Seems straightforward.
You could use an Arduino Nano. Use Serial for the 115200-baud side and SoftwareSerial for the 9600-baud side. Each time through loop(), read and buffer a character from each interface that has a character available. If the character indicates the end of a line ('\n' on 9600, '\n' on 115200?) process the line and send whatever output it causes.
I think this is probably the route I'll go down. [mrburnette] raised a good point about speed but I think the timeouts for reply are in the range of seconds before an error is thrown so it should be fast enough without the state machine solution. There seems to be a good example from the SoftwareSerial library that could be easily adapted.
For anyone finding this thread later on I'll post back in a few weeks if I make progress. Thanks all!
I designed this board with this exact sort of application in mind. It's not directly Arduino-like, but it does use an ATtiny1634, which is supported by Spence Konde's ATtinyCore
I've never actually built one up (haven't needed it, even though it seemed like a good idea at the time.) So it's not actually tested. If you're in the US, I could even send you a blank board...