Writing to UART via Circuits.UART

I have one of these tables… https://www.autonomous.ai/

The rj11 on the jcb35n control box for the table is connected to the raspberry pi.

I am able to connect to the serial port on my rapspvberry pi (ttyAMA0) connected to the jcb35n control box and read the data coming in with the instructions here https://embedded-elixir.com/post/2019-01-18-nerves-at-home-desk-controller/ using the ciruits.uart
https://github.com/elixir-circuits/circuits_uart
The difference is I am using the rj11 jack on the control box to communicate with the raspberry pi instead of the rj45.

What I am struggling with is the ability to write back to the uart to set the height of the table. So the question is can I issue a write with the height of the table and the table will adjust?

Any help would be greatly appreciated.

Saqi

1 Like

This kind of just depends. You can write serial data, but you need to know what the other end is expecting (or if it even is expecting data at all on serial)

In most cases with this desk, it’s not. Or, I’ve never been able to correctly guess the data structure to elicit actions.

However, the up/down motions of most these desks controllers are simple. 2 of the wires should be an up and a down wire. Connecting one of those (let’s say up) to ground will make it go that direction. For that case, you’d connect it to a GPIO pin and put that pin HIGH to make that action work, and LOW when you want it off.

RJ11 vs RJ45 shouldn’t matter. That’s just the size of connector and how many wires there are. If it’s RJ11 with 6 wires, 2 of those are prob the up and down wires. If there is only 4 wires, you might need to look around the controller to find the up down. Or you just have to reverse engineer the messages being read from the controller when moving to see if any provide clue to a message you can write to the wire to make it move (which, again, I think is very unlikely to be needed)

I appreciate the detailed response. So here is what the back story of this is …

The autonomous smart desk was supposed to have voice commands and you could just tell the desk to set the height you wanted. This never worked out of the box. So I kept trying to reach support and they kept promising but never delivered on the software. So I decided to dismantle their black box. This is not the control box (jcb35n) for the legs it was a second box attached to the desk.

Inside it I found a raspberry pi 2b, which had a usb wifi dongle, a usb sound card with mic and speaker attached to it. Unfortunately I have lost the original memory card otherwise life would have been much easier if we could have just looked in it.

The raspberry pi also has the connection to the control box (jcb35n) via a phone cable with rj11 on one end and the other end is hooked up to j8 header pins 6, 8 and 10.

On this raspberry pi I installed a fresh raspbian lite and setup elixir circuits.uart to check it out.

All the instructions worked until the write. So if the control box uses the rj45 port and rj11 port similarly then we should be able to set the memory fields as the touch pad is able to do that. Since none of the gpio pins are attached from the raspberry pi to the rj11 cable I cant directly test the up /down buttons.

As I was writing this may be I can connect 2 out of the remaining 3 wires in the rj11 cable (6 wire) and hook them up to gpio pins… !! brb …

This is fascinating. They gave you a control box with an rpi2 in it?! Cool

Where are the manual up/down buttons? With the RPI? Do you have uart messages when you hold one of those buttons?

With this setup, I would guess the main controller has the up/down pins and you might be right that the rpi2 is somehow supposed to tell it what to do.

Maybe if you have some pictures, code, and responses to post up somewhere, we could look for anything suspicious

6 wires in “rj11” would be rj12 just to nitpick…

normally you would measure voltage with a multimeter on the wires or the plug on the board - you should be able to find ground/power and rx/tx - be careful if you find negative voltage - then you’ll need something like a Max485/max232 https://www.ebay.com/itm/MAX232CSE-Transfer-Chip-RS232-To-TTL-Converter-Module-COM-Serial-Board-AD/112071858489 to convert it to ttl, and not fry your board…

but since yours came wired up, it should be ok - it’s the original wire right?

think it’s just ignoring your commands since they are not valid/checksumming/addressed to device etc.

can you post what it’s sending? in binary << x, y, z >> is fine…

think it’s something like:

        frameObj->StartByte1 = arrayData[0];
        frameObj->StartByte2 = arrayData[1];
        frameObj->LengthOfParams = arrayData[2];
        frameObj->ProductId = arrayData[3];
        frameObj->ComponentId = arrayData[4];
        frameObj->Instruction = arrayData[5];
        frameObj->Address = arrayData[6];
        frameObj->Params[0] = arrayData[7];
        frameObj->Params[1] = arrayData[8];
        frameObj->CheckSum = arrayData[9];
        frameObj->EndByte1 = arrayData[10];
        frameObj->EndByte2 = arrayData[11];

try and dissect this one https://github.com/quangthanh010290/smartdesk_kid/blob/416ebf807030f693bd8df0e3b26a583dcf4468e0/my_libs/Devices/AutonomousCommFrame.c and other stuff in this repo and else where on github to figure out the binary format…

think you need the product_id, address, and component_id to send commands to it - and figure out to checksum it correctly…


// move up
tx[0] = 0xFF; // Start Byte 1
tx[1] = 0xFF; // Start Byte 2
tx[2] = 0x02; // length
tx[3] = ProductId.SmartDesk; //product id
tx[4] = ComponentId.UpDownMotor; // component id
tx[5] = Instructions.Write; // instruction
tx[6] = ControlTableAddress.Up; // address
tx[7] = 0x01; // param 1
tx[8] = 0x01; // param 2
tx[9] = 0x0F; // check sum
tx[10] = 0xFA;// stop byte 1
tx[11] = 0xFA;// stop byte 2
len = 12;
mReq.putBytes(tx,len);
printf(“Set Desk Move Up\n”);
printf(“Sending Data to Desk…\n”);

find ProductId.SmartDesk etc here: https://github.com/quangthanh010290/smartdesk_kid/blob/master/my_libs/Devices/AutonomousCommFrame.h

can you try sending it << 255, 255, 2, 3, 3, 2, 3, 1, 1, 15, 250, 250 >> be ready to send it a stop in case it works…: << 255, 255, 2, 3, 3, 2, 5, 1, 1, 11, 250, 250 >>

happy new year… back from the dead with a new years resolution to try and get this desk working… @outlog I tried your suggestion didnt do anything…

iex(1)> {:ok, pid} = Circuits.UART.start_link
{:ok, #PID<0.160.0>}
iex(2)>   Circuits.UART.open(pid, "COM14", speed: 9600, active: true)
{:error, :enoent}
iex(3)> Circuits.UART.open(pid, "TTYAM0", speed: 9600, active: true)
{:error, :enoent}
iex(4)> Circuits.UART.enumerate
%{"ttyAMA0" => %{}}
iex(5)> Circuits.UART.open(pid, "TTYAMA0", speed: 9600, active: true)
{:error, :enoent}
iex(6)> Circuits.UART.open(pid, "ttyAMA0", speed: 9600, active: true)
:ok
iex(7)> flush
{:circuits_uart, "ttyAMA0", <<242, 1, 3, 1, 160, 15, 180>>}
{:circuits_uart, "ttyAMA0", <<242, 1, 3, 1, 161, 15, 181>>}
{:circuits_uart, "ttyAMA0", <<242, 1, 3, 1, 162, 15, 182>>}
{:circuits_uart, "ttyAMA0", <<242, 1, 3, 1, 164, 15, 184>>}
{:circuits_uart, "ttyAMA0", <<242, 1, 3, 1, 166, 15, 186>>}
{:circuits_uart, "ttyAMA0", <<242, 1, 3, 1, 166, 15, 186>>}
{:circuits_uart, "ttyAMA0", <<242, 1, 3, 1, 166, 15, 186>>}
{:circuits_uart, "ttyAMA0", <<242, 1, 3, 1, 166, 15, 186>>}
{:circuits_uart, "ttyAMA0", <<242, 1, 3, 1, 166, 15, 186>>}
{:circuits_uart, "ttyAMA0", <<242, 1, 3, 1, 166, 15, 186>>}
{:circuits_uart, "ttyAMA0", <<242, 1, 3, 1, 166, 15, 186>>}
{:circuits_uart, "ttyAMA0", <<242, 1, 3, 1, 166, 15, 186>>}
{:circuits_uart, "ttyAMA0", <<242, 1, 3, 1, 166, 15, 186>>}
{:circuits_uart, "ttyAMA0", <<242, 1, 3, 1, 166, 15, 186>>}
{:circuits_uart, "ttyAMA0", <<242, 1, 3, 1, 166, 15, 186>>}
{:circuits_uart, "ttyAMA0", <<242, 1, 3, 1, 166, 15, 186>>}
{:circuits_uart, "ttyAMA0", <<242, 1, 3, 1, 166, 15, 186>>}
{:circuits_uart, "ttyAMA0", <<242, 1, 3, 1, 166, 15, 186>>}
:ok
iex(8)> flush
:ok
iex(9)> Circuits.UART.write(pid, << 255, 255, 2, 3, 3, 2, 3, 1, 1, 15, 250, 250 >> )
:ok
iex(10)> Circuits.UART.write(pid, "<< 255, 255, 2, 3, 3, 2, 3, 1, 1, 15, 250, 250 >>")
:ok
iex(11)> flush
:ok```