Help with hardware flow control on Argon

I’m trying to connect to an Acconeer XM132 which requires RTS/CTS uart. I’m sending it register write requests as per their documentation examples, but not receiving a register write response. Specifically register write responses have a start byte of 0xCC, and I only receive 0x00.

Argon docs say:

On Gen 3 devices (Argon, Boron, Xenon), flow control is available on Serial1 D3(CTS) and D2(RTS). If you are not using flow control (the default), then these pins can be used as regular GPIO.

SERIAL_FLOW_CONTROL_NONE - no flow control
SERIAL_FLOW_CONTROL_RTS - RTS flow control
SERIAL_FLOW_CONTROL_CTS - CTS flow control
SERIAL_FLOW_CONTROL_RTS_CTS - RTS/CTS flow control

Does this mean that I just have to set Serial1.begin(115200, SERIAL_FLOW_CONTROL_RTS_CTS); and the flow control will be handled, or do I also have to manually set and reset the RTS and CTS pins? I have tried it both ways and neither has worked.

Any help would be greatly appreciated.

Code:

#define MODE_SELECTION_REGISTER 0x02
#define POWER_BINS_SERVICE 0x01
#define ENVELOPE_SERVICE 0x02
#define SPARSE_SERVICE 0x04
#define DISTANCE_SERVICE 0x200
#define PRESENCE_SERVICE 0x400

#define MAIN_CONTROL_REGISTER 0x03
#define STOP_SERVICE 0x00
#define START_SERVICE 0x03

#define STREAMING_CONTROL_REGISTER 0x05
#define UART_OFF 0x00
#define UART_ON 0x01

#define CTS D3
#define RTS D2

//#define MANUALPINS

SerialLogHandler logHandler(LOG_LEVEL_INFO);

void setup() {

Log.info(“starting setup”);

//Start serial communication
Serial1.begin(115200, SERIAL_FLOW_CONTROL_RTS_CTS);

}

void loop() {

Log.info(“you’re looping”);

static unsigned char register_write_response[128]; //max size of serial buffer = 128 bytes
static unsigned char register_write_request[10] = {0xCC, 0x05, 0x00, 0xF9, MAIN_CONTROL_REGISTER, STOP_SERVICE, 0x00, 0x00, 0x00, 0xCD};

#if defined(MANUALPINS)
//set CTS = pin D3 low and RTS = pin D2 high to stop receiving, and transmit
pinResetFast(CTS);
pinSetFast(RTS);
#endif

Serial1.write(register_write_request, 10);

#if defined(MANUALPINS)
//brief pause to make sure transmission is complete
delay(10);

//set CTS high and RTS low to receive response
pinResetFast(RTS);
pinSetFast(CTS);
#endif

while(Serial1.available()) {
//write response should start with 0xCC per acconeer docs
register_write_response[0] = Serial1.read();
}

Log.info(“register_write_response[0] = 0x%02X”, register_write_response[0]);
delay(500);

}

The result in both cases - MANUALPINS defined and not defined - is:

0000012997 [system] INFO: Cloud connected
0000012997 [app] INFO: starting setup
0000012998 [app] INFO: you’re looping
0000013010 [app] INFO: register_write_response[0] = 0x00
0000013511 [app] INFO: you’re looping
0000013521 [app] INFO: register_write_response[0] = 0x00
0000014022 [app] INFO: you’re looping
0000014032 [app] INFO: register_write_response[0] = 0x00
0000014762 [comm.protocol] INFO: Posting ‘S’ describe message
0000014765 [comm.dtls] INFO: session cmd (CLS,DIS,MOV,LOD,SAV): 4
0000015011 [comm.dtls] INFO: session cmd (CLS,DIS,MOV,LOD,SAV): 3
0000015012 [comm.protocol] INFO: rcv’d message type=1
0000015012 [app] INFO: you’re looping
0000015023 [app] INFO: register_write_response[0] = 0x00
0000015523 [comm.protocol] INFO: Posting ‘A’ describe message
0000015525 [comm.dtls] INFO: session cmd (CLS,DIS,MOV,LOD,SAV): 4
0000015525 [comm.dtls] INFO: session cmd (CLS,DIS,MOV,LOD,SAV): 3
0000015525 [comm.protocol] INFO: rcv’d message type=1
0000015526 [app] INFO: you’re looping
0000015536 [app] INFO: register_write_response[0] = 0x00
0000016038 [comm.protocol] INFO: rcv’d message type=8
0000016038 [app] INFO: you’re looping
0000016049 [app] INFO: register_write_response[0] = 0x00
0000016549 [app] INFO: you’re looping
0000016560 [app] INFO: register_write_response[0] = 0x00
0000017060 [app] INFO: you’re looping
0000017071 [app] INFO: register_write_response[0] = 0x00
0000017571 [app] INFO: you’re looping
0000017582 [app] INFO: register_write_response[0] = 0x00
0000018082 [app] INFO: you’re looping
0000018093 [app] INFO: register_write_response[0] = 0x00
0000018593 [app] INFO: you’re looping
0000018604 [app] INFO: register_write_response[0] = 0x00
0000019104 [app] INFO: you’re looping
0000019115 [app] INFO: register_write_response[0] = 0x00
0000019615 [app] INFO: you’re looping

Here is a Happy Thanksgiving to you! :slightly_smiling_face:

I would try to get all the delay() statements removed from the loop(). Here is a write up @rickkas7 did a while back which may help with examples on how to do this.

https://github.com/rickkas7/serial_tutorial

There is a section called “Avoid delay in loop”. In it there is an example which could be applied in removing the delay for this code in particular:

Log.info(“register_write_response[0] = 0x%02X”, register_write_response[0]);
delay(500); // try to remove this delay() and all others from loop()

Hi, I know that’s should be obvious but … just to be sure. How did you wired-up your Argon with XM123 ?
from documentation follows that:

XM123 UART_TX become your Argon_RX ( host_RX ) 
XM123 UART_RX become your Argon_TX ( host_TX )
XM123 UART_CTS become your Argon_RTS ( host_RTS "D3" )
XM123 UART_RTS become your Argon_CTS ( host_CTS "D2" )

Also I personally thinking that you should not needed to control CTS/RTS pins manually this should be handled by this line
in your setup:

Serial1.begin(115200, SERIAL_FLOW_CONTROL_RTS_CTS);

But regarding to this post:


nobody even from Particle do not know how or why this is not working as the question never get any constructive answer for more than a year !

Maybe @rickkas7 or @ScruffR can help a little more here
:stuck_out_tongue_winking_eye:

I have no idea what you mean. What is obvious??

too bad :frowning:
the obvious here was my understanding that with UART communication RX and TX should be always “crossed” the RX of one dev should be TX on the other side and vice versa.
Personally I make this mistake many times but I didn’t know that’s applay to CTS and RTS pins as well so I lerned something again
Also I said:

I guess I claryfy for you my usage of word “obvious” in here and please let’s keep focus on the topic

Thanks for your clarification. I was hoping you might have read the information from my original post. And, implemented some changes to your code. But, it seems that did not occur. Well, my hope is someone else can take a crack at assisting you.

Have a good holiday! :smiley:

Hey @robc I’m confused completely right now :see_no_evil: as firstly this is not my code this is @Fargoran code
secondary I agree with you about removing all delays() from loop 100% as I read @rickkas7 serial tutorial long time ago and I’m familiar with it, but is a little outdated as didn’t cover Gen 3 Dev flow control and even Particle documentation regarding to flow control is a little poor and didn’t provide fully explanation how to deal with that and can be confused.

so I just want to help @Fargoran as you ! that’s why I ask @Fargoran how the wires are connected between XM123 and Argon ?

Best regards and Have a good holiday to ! :+1:

@robc Thanks, happy thanksgiving to you as well! Also I think you were replying to dreamER in your last message as if they were the OP, but that isn’t the case. I have read the information in your original post, and I made the suggested change to my code. Unfortunately removing the delays in my code made no difference. At this point I suspect the problem is the Acconeer, I’ll provide more details below.

@dreamER I had a co-worker double check my wiring and it is correct, although thank you for the sanity check.

I agree we could use some better clarity/documentation from the Particle team around this! I have made some progress on this issue though:


I disconnected the Acconeer from the Argon, and connected a scope to the Argon TX out. It was pulled high and remained pulled high no matter if I was setting the pins in the code or not. Similarly, probing the CTS and RTS pins with the scope showed that RTS remained pulled high, and CTS remained floating, no matter if I was using pinSetFast/pinResetFast or not.

The only way I could get the Argon to transmit correctly in RTS/CTS mode was to manually pull the Argon’s CTS pin to ground. Once I did that, I could see the byte transmission out of the Argon’s TX pin on the scope clear as day. Unfortunately the out-of-box firmware that comes with the Acconeer maintains its RTS pin high at all times, so my next step with this issue is to look at why that is and how to change it.

That being said, @dreamER if you have access to a scope and two Argons, you could wire this up and test if pinSetFast/pinResetFast is required or if serial1.write() and serial1.read() handle it automatically. Although I agree again with your original statement that we could use clarity from the Particle team on this, because that is an awful lot of work just to clear up something the docs have obfuscated.


P.S. a small request - please don’t default to “he/his” on tech forums. I’m a woman, and women have been working in STEM fields for quite awhile now, so it always makes me a little sad that people still automatically assume I’m a dude. If using s/he and his/her is too cumbersome, consider that “they/their” has been officially adapted by the dictionary now. (See definitions 3a and 3b) I would feel a lot more welcome in the tech community if more people started adopting either one. Thanks.

@Fargoran My apologies I’m really sory for that. I corrected my previus post accordingly.
As English is not my native language and I’m mostly focusing on T/S here on the forum, you are apsolutely right I asumed that you are buddy automatically :see_no_evil: sorry one more time. I hope you will forgive me :pray:
I’m gonna lern the lesson for future

unfortunately I have just one Argon and no scope but if time will allow me I’ll try to connect Argon to my RS232 MOXA Uport USB converter (as can handle CTS/RTS flow control) with some signal shifter and then will make some Python script to pretend Dev which require CTS/RTS. I’m really curius what’s going on here :face_with_raised_eyebrow:

OOPS! Hey, I am sorry for that goof up! My apologies to both @dreamER and @Fargoran! Thanks for the heads up! Geewiz! And my mistake was made BEFORE I had any wine at the holiday feast table…
Happy Black Friday to you both!

@Fargoran, this makes me wonder if the Acconeer is really using hardware handshaking or not. If you pull the CTS pin low with a pull-down, do the communications between the Argon and the Acconeer work?

Does the Acconeer provide a DTR pin on its connector? If that pin isn’t set active, the device will not transmit. You may want to consider using a NULL modem connector/cable to get communications going.

BTW, we need more women in STEM (or STEAM for some) so glad you are posting here.

3 Likes

So! After more than a week of back-and-forth with Acconeer support they finally looked at the schematic of my wiring (I sent it three times! argh!) and they found the issue.

It turns out that on the XE132 evaluation board the TX/RX cross, and the CTS/RTS cross, are already performed between the GPIO pin header and the radar module itself. @peekay123 and @dreamER, if you’re curious you can check out the schematic on page 14 of the User Guide. Of course this isn’t documented anywhere more obvious, and it does completely defy UART standards… but wiring the RX pin of my Argon to the RX pin of the Acconner, ditto for TX pins, and tying the Acconeer’s RTS pin to ground, got the two boards talking over UART without needing hardware flow control.

I can’t find an emoji that adequately captures my feelings about Acconeer right now… some combination of :grimacing: :face_with_symbols_over_mouth: :sob:?

Also…
@dreamER Thank you for so graciously accepting my correction about your pronoun use! And @peekay123 thank you for stating your support for women in STEM… obviously this community is much nicer and more welcoming than the usual social media/forums that I am used to… makes my day! :grinning:

2 Likes

@Fargoran, persistence pays off again! The RS232 standard is the most abused standard I’ve ever worked with so I’m not surprised Acconeer did that. Perhaps disappointed is a better word, especially and specifically because of poor documentation. Good work!

Way to go! Great to hear about this happy ending.

which indicate that I was right :slight_smile:
Simple conductivity check with multimeter on „beep mode” will saved your time and rescue from frustration :slight_smile: anyway I’m glad that you solve this out ! Best Regards and merry Christmas!!!

@dreamER

Actually, no, the wiring you suggested was NOT correct, which is why I was so frustrated with Acconner. They’ve defied the standard. You had suggested:

XM123 UART_TX become your Argon_RX ( host_RX ) 
XM123 UART_RX become your Argon_TX ( host_TX )
XM123 UART_CTS become your Argon_RTS ( host_RTS "D3" )
XM123 UART_RTS become your Argon_CTS ( host_CTS "D2" )

But this cross was already performed for me between the XM132’s evaluation board and the XM132 radar module, ON the evaluation board ITSELF. The wiring that worked between my Argon and the XM132 evaluation board was:

XM132 TX to Argon TX
XM132 RX to Argon RX
XM132 RTS (instead of CTS) to ground to disable hardware flow control.

If you check out the schematic I referenced on page 14 of the User Guide, you’ll see where they perform the cross for me.

Thank you for trying though, you did give the correct advice according to the UART standard, lol. As I said in my previous post, I’m not too impressed that Acconeer didn’t document this more clearly.

I can’t agree with you if “cross” was done somewhere else and you will get the multi meter on “beep mode” disconnect all power source and then place 1 probe on lets say TX of Argon and second probe on Rx of Acconner and you do not hear beeeeeeeeepppp that’s indicate right away that something is not right that’s why I recommended to physically check the connection between this 2 devices

I don’t see anything in your original comment about checking the connections with the multimeter in diode mode, it only suggests checking my wiring matched the uart standard, which I had, and was not the correct way to do things as per the Acconeer user guide I linked to. You only brought up the multimeter thing after you said you were right about the wiring.

Checking how the wiring was connected was not the source of my frustration because I checked it with the 'scope and could clearly see something was wrong. If you look at my second post I talk about it there. The frustration came from Acconeer not following uart standards, and the fact that it took them three support tickets before they looked at my schematic and found the problem.

Edit - I think we may be not understanding each other as well, because your multimeter suggestion doesn’t make any sense. There is some cross-talk between us, if you will pardon the pun. :stuck_out_tongue: I can clearly see that the Argon and the Acconeer are connected together correctly on my breadboard. If I place the multimeter in parallel with the connection on the breadboard, it will always beep because of the connection in the breadboard. If I disconnect the TX of Argon and RX of Acconeer from the breadboard and then connect them via the probes on the multimeter, all I have done is connect Acconeer-multimeter-Argon in series.

In diode mode a multimeter applies a small voltage across its leads and then looks to see if it can detect current, indicating a break or a short circuit. It always has to be connected in parallel with the diode or whatever else it is testing. Connecting it in series won’t tell me anything, other than that both the Acconeer RX pin and the Argon TX pin are not shorted directly to the ground the two boards share.