As I said in the Arduino linking routines thread:

A friend lent me an old Norland robot and I am trying to control the robot with an arduino by sending commands from the Norland manual found at http://www.smallrobot.com/Instructions.pdf .

For example, I would like to send "SEND({122,100})" to cause this robot to drive forward for 5 seconds.

I'm using the library posted to GitHub and attempting to adapt the key press sending example. So far I've been unable to get the robot to respond. My latest attempt can be found at: https://gist.github.com/acspike/0011efa65b576e8f00f3

Perhaps there are obvious mistakes or suggestions you can give me?
I must first salute you for figuring out how to represent a two-element list in the TI list format unaided, so you're on the right track! Unfortunately, the sequence of messages for sending a list to the robot requires a few more back-and-forth messages than you have there. Specifically, you'll need to use the CBL2 protocol. I have begun documenting the CBL2 protocol here. Try imitating the sequence of commands for Send({0}) or so, if you have the time and inclination. I'm also going to add a CBL2 module to the library to simplify interacting with the Get() and Send() commands, but that will be written as if the Arduino was the CBL2; you want code that makes the Arduino speak the calculator side of things. Hope this helps!
Well, I attempted to write a sketch that naively parrots the CBL2 protocol to the robot, but it didn't do much. Looking a little deeper, I don't think it even gets as far as sending the first byte. So I'm blocked from implementing even a dumb version of the protocol until I can get the low level communication working.

My latest non functioning version is here:

https://gist.github.com/acspike/0011efa65b576e8f00f3

Please let me know if that looks more reasonable.
Scratch that. I noticed it wasn't fully plugged in. It isn't 100% reliable but the robot does move forward occasionally now using the code linked above.
acspike wrote:
Scratch that. I noticed it wasn't fully plugged in. It isn't 100% reliable but the robot does move forward occasionally now using the code linked above.
That's great news! I've gotten as far as pushing code to my repository that will emulate the CBL2 (as the robot does); I'll also try to work on the code to make the Arduino pretend to be the calculator side. Do you have any insight into why the movement is sporadic?
Not yet. I made sure to make the serial logs for each failing message distinct so I could see where things were going wrong, but I didn't investigate it very fully yet. Various lines would print and there didn't seem to be any pattern. Could be as simple as poor connections to the arduino.

You might consider some way to optionally pass a serial port object into TILP to provide some sort of debug log. The return values are helpful, but something more granular might be useful to give visibility into nested calls (like sendByte()). Might be useful to people like me who don't have any sophisticated test equipment.
acspike wrote:
Not yet. I made sure to make the serial logs for each failing message distinct so I could see where things were going wrong, but I didn't investigate it very fully yet. Various lines would print and there didn't seem to be any pattern. Could be as simple as poor connections to the arduino.
Makes sense. I hope our ongoing tandem will work help uncover the clues we need to get this working reliably.

Quote:
You might consider some way to optionally pass a serial port object into TILP to provide some sort of debug log. The return values are helpful, but something more granular might be useful to give visibility into nested calls (like sendByte()). Might be useful to people like me who don't have any sophisticated test equipment.
A superb idea, and one that I have now implemented. Check out this commit to the ArduinoTILP library.
Thanks!

Here's an excerpt of the messages I see on the serial console:

Code:

Sending message type 0xC9 to endpoint 0x82 length 11

Get CTS returned -1

Sending message type 0x56 to endpoint 0x82 length 0

Send ACK CTS returned -2

Sending message type 0x15 to endpoint 0x82 length 20

Sending message type 0x92 to endpoint 0x82 length 0

Send EOT returned -2

Sending message type 0xC9 to endpoint 0x82 length 11

Send RTS returned -2

Sending message type 0xC9 to endpoint 0x82 length 11

Send RTS returned -2

Sending message type 0xC9 to endpoint 0x82 length 11

Send RTS returned -2

Sending message type 0xC9 to endpoint 0x82 length 11

Send RTS returned -2

Sending message type 0xC9 to endpoint 0x82 length 11

Sending message type 0x56 to endpoint 0x82 length 0

Sending message type 0x15 to endpoint 0x82 length 20

Sending message type 0x92 to endpoint 0x82 length 0

Get ACK EOT returned -1

Sending message type 0xC9 to endpoint 0x82 length 11

Get CTS returned -1

Sending message type 0x56 to endpoint 0x82 length 0

Send ACK CTS returned -2

Sending message type 0x15 to endpoint 0x82 length 20

Sending message type 0x92 to endpoint 0x82 length 0

Send EOT returned -2

Sending message type 0xC9 to endpoint 0x82 length 11

Send RTS returned -2

Sending message type 0xC9 to endpoint 0x82 length 11

Send RTS returned -2

Sending message type 0xC9 to endpoint 0x82 length 11

Send RTS returned -2

Sending message type 0xC9 to endpoint 0x82 length 11

Send RTS returned -2

Sending message type 0xC9 to endpoint 0x82 length 11

Sending message type 0x56 to endpoint 0x82 length 0

Sending message type 0x15 to endpoint 0x82 length 20

Sending message type 0x92 to endpoint 0x82 length 0

Get ACK EOT returned -1


It looks rather reliable today. There is a 500ms delay at the end of loop. Perhaps there is a rate limit for how quickly you are allowed to send commands? (ie. there are fewer failures if I raise the delay)

My biggest annoyance at the moment is that I can't make the wheels move for more than ~.5 seconds. A robot that moves for a half second and needs a 2 second break isn't particularly exciting. Smile
It looks like all the get()s are failing to me, for starters. I'm working on looking into that for my CBL2 layer anyway at the moment.
Here's the serial log after tonight's fixes:


Code:

ending message type 0xC9 as endpoint 0x82 length 11

Send RTS returned -2

Sending message type 0xC9 as endpoint 0x82 length 11

Send RTS returned -2

Sending message type 0xC9 as endpoint 0x82 length 11

Send RTS returned -2

Sending message type 0xC9 as endpoint 0x82 length 11

Send RTS returned -2

Sending message type 0xC9 as endpoint 0x82 length 11

Receiving message type 0x56 from endpoint 0x12 length 0

Receiving message type 0x9 from endpoint 0x12 length 0

Sending message type 0x56 as endpoint 0x82 length 0

Sending message type 0x15 as endpoint 0x82 length 20

Receiving message type 0x56 from endpoint 0x12 length 0

Sending message type 0x92 as endpoint 0x82 length 0

Get ACK EOT returned -1

Sending message type 0xC9 as endpoint 0x82 length 11

Receiving message type 0x56 from endpoint 0x12 length 0

Get CTS returned -1

Sending message type 0x56 as endpoint 0x82 length 0

Send ACK CTS returned -2

Sending message type 0x15 as endpoint 0x82 length 20

Receiving message type 0x56 from endpoint 0x12 length 0

Sending message type 0x92 as endpoint 0x82 length 0

Send EOT returned -2

Sending message type 0xC9 as endpoint 0x82 length 11

Send RTS returned -2

Sending message type 0xC9 as endpoint 0x82 length 11

Send RTS returned -2

Sending message type 0xC9 as endpoint 0x82 length 11

Send RTS returned -2

Sending message type 0xC9 as endpoint 0x82 length 11

Send RTS returned -2

Sending message type 0xC9 as endpoint 0x82 length 11

Receiving message type 0x56 from endpoint 0x12 length 0

Receiving message type 0x9 from endpoint 0x12 length 0

Sending message type 0x56 as endpoint 0x82 length 0

Sending message type 0x15 as endpoint 0x82 length 20

Receiving message type 0x56 from endpoint 0x12 length 0

Sending message type 0x92 as endpoint 0x82 length 0

Get ACK EOT returned -1

Sending message type 0xC9 as endpoint 0x82 length 11

Receiving message type 0x56 from endpoint 0x12 length 0

Get CTS returned -1

Sending message type 0x56 as endpoint 0x82 length 0

Send ACK CTS returned -2

Sending message type 0x15 as endpoint 0x82 length 20

Receiving message type 0x56 from endpoint 0x12 length 0

Sending message type 0x92 as endpoint 0x82 length 0

Send EOT returned -2

I figured out what was making it stutter. The loop kept sending new commands without waiting for the robot to finish driving. Evidently some packets interrupt the driving. Extending the delay in the loop alleviates this problem. There still seems to be a significant delay between sending the packet and driving. Perhaps I will install a button to initiate the driving so that I can understand that better.

Current Code:
https://gist.github.com/acspike/0011efa65b576e8f00f3


Code:

Sending message type 0xC9 as endpoint 0x82 length 11

Receiving message type 0x56 from endpoint 0x12 length 0

Receiving message type 0x9 from endpoint 0x12 length 0

Sending message type 0x56 as endpoint 0x82 length 0

Sending message type 0x15 as endpoint 0x82 length 20

Receiving message type 0x56 from endpoint 0x12 length 0

Sending message type 0x92 as endpoint 0x82 length 0

Get ACK EOT returned -1

Sending message type 0xC9 as endpoint 0x82 length 11

Receiving message type 0x56 from endpoint 0x12 length 0

Get CTS returned -1

Sending message type 0xC9 as endpoint 0x82 length 11

Send RTS returned -2

Sending message type 0xC9 as endpoint 0x82 length 11

Send RTS returned -2

Sending message type 0xC9 as endpoint 0x82 length 11

Receiving message type 0x56 from endpoint 0x12 length 0

Receiving message type 0x9 from endpoint 0x12 length 0

Sending message type 0x56 as endpoint 0x82 length 0

Sending message type 0x15 as endpoint 0x82 length 20

Receiving message type 0x56 from endpoint 0x12 length 0

Sending message type 0x92 as endpoint 0x82 length 0

Get ACK EOT returned -1

Sending message type 0xC9 as endpoint 0x82 length 11

Receiving message type 0x56 from endpoint 0x12 length 0

Get CTS returned -1

Sending message type 0xC9 as endpoint 0x82 length 11

Send RTS returned -2

Sending message type 0xC9 as endpoint 0x82 length 11

Send RTS returned -2

Sending message type 0xC9 as endpoint 0x82 length 11

Receiving message type 0x56 from endpoint 0x12 length 0

Receiving message type 0x9 from endpoint 0x12 length 0

Sending message type 0x56 as endpoint 0x82 length 0

Sending message type 0x15 as endpoint 0x82 length 20

Receiving message type 0x56 from endpoint 0x12 length 0

Sending message type 0x92 as endpoint 0x82 length 0

Get ACK EOT returned -1



Perhaps we need the CBL2 equivalent of select or epoll?
Off the top of my head, I notice that you try to perform an EOT/ACK EOT, which necessarily goes poorly. Weirdly, the calculator itself does not do the EOT/wait for ACK EOT when doing a Send(). Does anything change if you remove that?
If I remove EOT it doesn't work at all. But it does work similarly if I omit just the get ACK EOT.

I'll have to look back at the other thread, but I thought I saw EOT on the Send commands but not the Get.[/quote]
acspike wrote:
If I remove EOT it doesn't work at all. But it does work similarly if I omit just the get ACK EOT.

I'll have to look back at the other thread, but I thought I saw EOT on the Send commands but not the Get.
Ah, you're absolutely right; I misremembered my own notes. Regardless, it seems problematic that the ACK EOT isn't working properly, and the problem is that you have { CALC82, EOT, data_len_lsb, 0x00 }; rather than { CALC82, EOT, 0x00, 0x00 };. Hope that helps.
I'll try that.

{ CALC82, EOT, 0x00, 0x00 } matches what I would expect from the link guide.

But { CALC82, EOT, data_len_lsb, 0x00 } is what I see in the captures posted. And also what I thought: https://github.com/KermMartian/ArTICL/blob/master/TICL.cpp#L66
might imply.

Length 0x00 0x00 doesn't seem to help the ACK EOT come through.
The captures have that because the calculator itself is too lazy to bother clearing the length bytes of the header when the message by definition cannot have a body. But you make the excellent point that those bytes are irrelevant anyway, since the CBL2 device (and the robot emulating a CBL2) ignore them. I would not be surprised if the failure to get the ACK EOT is still contributing to the delay before it starts driving, yet I don't understand why the ACK EOT would not be sent properly.
With Send() triggered by a button press and I can see the behavior a little better than I could with the loop.

On the first button press this happens:

Code:
Sending message type 0xC9 as endpoint 0x82 length 11
Receiving message type 0x56 from endpoint 0x12 length 0
Receiving message type 0x9 from endpoint 0x12 length 0
Sending message type 0x56 as endpoint 0x82 length 0
Sending message type 0x15 as endpoint 0x82 length 20
Receiving message type 0x56 from endpoint 0x12 length 0
Sending message type 0x92 as endpoint 0x82 length 0
Get ACK EOT returned -1


And no movement takes place. Immediately upon the second button press moving starts and these messages are printed:

Code:
Sending message type 0xC9 as endpoint 0x82 length 11
Receiving message type 0x56 from endpoint 0x12 length 0
Get CTS returned -1


And so if I start sending a second time the delay mostly goes away.
It seems to me that the robot is expecting that ACK EOT to succeed, and the fact that it didn't is why the movement command didn't take effect. Presumably the 0xC9 message getting sent breaks the robot out of whatever waiting loop it was in. May I recommend that you retry the ACK EOT get() a few times?
That was my first inclination also. So I put ACK EOT into a loop. It never succeeds. Which makes me think the robot expects something else entirely.

The copyright date on circuit board on my robot says 2002 (Ver. 1.1). When did the transition from CBL to CBL2 take place? Could it be expecting CBL? Could CBL Send be slightly different?
acspike wrote:
The copyright date on circuit board on my robot says 2002 (Ver. 1.1). When did the transition from CBL to CBL2 take place? Could it be expecting CBL? Could CBL Send be slightly different?
It absolutely could. I think we need to either eavesdrop on the CBL protocol, or listen to the communication between the robot and a real calculator. Unfortunately, you have a robot and no calculator, and I have calculators galore and no robot.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 2
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement