Write to hardware serial Nano v3.0 (Dynamic Shark Joystick emulator)

Hello, i am trying to emulate a Wheelchair Joystick for the ‘Shark’ Controller made by Dynamic for wheelchairs.

I’ve the raw data, captured with Saleae Logic4.

(attached is capture image)

Gizmosmith http://gizmosmith.com/?p=586 settings helped me get my own Logic4 getting captures setup.

  • i would like to write it to Hard Ware Serial on my Nano(no particular reason for this other than in reading about it. I thought i understood that the timing was easier to keep tight ?)

  • Connect the Logic4 (Saleae Logic Analyzer) to the RX and Ground, read the data from Nano.

  • Confirm i have a small portion of the code running in the right format on the bus.

  • Run in a loop with 17microsecond pause between packets.

//i would then like to write libraries for each section of code and call from more simple sketch…but first steps first.

This is the code i am attempting to use,

void setup() {
  // put your setup code here, to run once:
  
 Serial.begin(38400, SERIAL_8E1);


}

void loop() {
  // put your main code here, to run repeatedly:
      Serial.write(0x60);   // Start bit " ' "(0x60)   Address ?
      Serial.write(192);   // Bit 1 "192"(0xC0)   Y axis data
      Serial.write(192);    // Bit 2 "192"(0xC0)   X axis data
      Serial.write(255);    // Bit 3 "255"(0xFF)   Speed max setting
      Serial.write(192);    // Bit 4 "192"(0xC0)   Speed fine tune ?
      Serial.write(128);    // Bit 5 "128"(0x80)   Horn off/ 130on
      Serial.write(140);    // Bit 6 "140"(0x8C)   Joystick on ?
      Serial.write(128);    // Bit 7 "128"(0x80)   Chair mode (128drive/129tilt)
      Serial.write(212);    // Bit 8 "212"(0xD4)   Some other XY modifier ?
      Serial.write(0x0F);    // End Bit "15"(0x0F)   End packet
      
      //Delay next idle packet 17ms till next idle sent if no input from Shark joystick
      delay(17);
}

It works but on the serial monitor ’ prints correctly but the rest comes out with other ASII characters.

And i cant get the Logic4 to trigger capture, tho i suspect thats because, i need some
write(high); // on sequence capture from shark Joystick
delay(293);
write(low);
delay(10.28); // after this the data packets from Joystick to motor controller inside wheelchair begin.

I am not sure if i put this in the
void setup () {
// do i put it here ?
}

or in the
void loop() {
//here if i want it to do more than once for testing.
}

Information : I have an acquired brain injury, i am trying to do a much bigger thing but this is the first step.

Doug La Rue has sent me working sketches for a Jazzy Gt but it is not working with the shark.
Sniffing of the output of the Arduino loaded with his sketch shows up pretty quickly why.

  1. I would eventually like to intercept the data from the Joystick and modify the X,Y values with information from some distance sensors mounted around the chair, re:stop user driving into walls…but let them back away.turn away.
  2. Add RC function to my own chair so i can use it to tow a boat dolly for me (semi wheelchair person trying to go fishing with greater independence)
  3. Add distance sensors to aid with obstacle avoidance (wife’s left side blindness from brain bleed in/around/between portion of brain with nerves running eyes to vision centers at rear of brain)
  4. Write or assist with the writing (or provision of data for the writing of) information for Libraries to be created for each power chair as i come across them.

delay(10.28);

You can’t delay for decimal milliseconds. That would be microseconds. Try this:

delayMicroseconds(10280);  //wait for 10.28msec

You also appear to have bits and bytes confused. Serial.write() will write a whole byte, 8 bits, plus the start bit, parity bit and stop bit you have specified with Serial.begin(). Because you use the word “bit” to describe the bytes you are sending, I’m not sure that I understand what you are trying to do.

What are you going to name your chair when it’s towing your boat without you in it? Batmobile?

Thank you for your reply,

Trying to recreate the packet of data that gets sent (img attched first post)

which is

// Start bit " ' "(0x60) Address ?
// Data 1 "192"(0xC0) Y axis data
// Data 2 "192"(0xC0) X axis data
// Data 3 "255"(0xFF) Speed max setting
// Data 4 "192"(0xC0) Speed fine tune ?
// Data 5 "128"(0x80) Horn off/ 130on
// Data 6 "140"(0x8C) Joystick on ?
// Data 7 "128"(0x80) Chair mode (128drive/129tilt)
// Data 8 "212"(0xD4) Some other XY modifier ?
// End bit "15"(0x0F) End packet

If i can send this correctly i can begin to write the library and just call the packet i need when i need it.

...maybe call it the Boat.Mobile1.0 :slight_smile:
I am also building an RC Fishing boat, have a Jetski hull in the garage ready to chop up :slight_smile:
My RC Lawnmower is here https://www.youtube.com/watch?v=8qRiEY_zdSc
My Wheelchair, ebike, scooter here (tv spot new inventors) erv1 New Inventors spot - YouTube
Blog on my sailability boat mod - RC/wireless/wired servo assist full size boats http://sailabilitygc.org/category/projects/

So what is incorrect about what the Arduino is sending? It looks like it should work.

Viewing this with the serial monitor is impossible as most of those characters are not printable. Your logic analyzer is the best tool. Can you get it to decode the serial stream and show the hex codes underneath?

oh, so i dont have the option to view with serial Monitor . Cool
yes its unreadable

Ive not yet been able to get the Logic4 to trigger, i must need that Drive RX high then low before sending.

something like this i guess, but i have wrong words for driving RX high i think , getting errors.

void setup() {

  Serial.begin(38400, SERIAL_8E1);
  Serial.write(high); // drive RX pin high
  delayMicroseconds(293);
  Serial.write(low); // drive RX pin Low
  delayMicroseconds(10280);  // after this the data packets from Joystick to motor controller inside wheelchair begin.

}

void loop() {

  Serial.write(0x60);   // Start bit " ' "(0x60)   Address ?
  Serial.write(192);   // Data 1 "192"(0xC0)   Y axis data
  Serial.write(192);    // Data 2 "192"(0xC0)   X axis data
  Serial.write(255);    // Data 3 "255"(0xFF)   Speed max setting
  Serial.write(192);    // Data 4 "192"(0xC0)   Speed fine tune ?
  Serial.write(128);    // Data 5 "128"(0x80)   Horn off/ 130on
  Serial.write(140);    // Data 6 "140"(0x8C)   Joystick on ?
  Serial.write(128);    // Data 7 "128"(0x80)   Chair mode (128drive/129tilt)
  Serial.write(212);    // Data 8 "212"(0xD4)   Some other XY modifier ?
  Serial.write(0x0F);    // End bit "15"(0x0F)   End packet

  //Delay next idle packet 17ms till next idle sent if no input from Shark joystick
  delay(17);
}

Maybe powering the Arduino from the usb is locking out the RX pin ? Ill scratch about for a battery and see

The USB serial will compete with any device you have plugged in to pins 0 and 1. However if you aren't sending anything from the computer then it shouldn't interfere.

You can't write high and low with serial. You can use digitalWrite(1, HIGH) to write to the TX pin but that won't work because the UART module was given control over that pin by Serial.begin(). You would have to call Serial.end(), then hold the pin high, then call Serial.begin(). That doesn't sound like a normal data protocol.

If you were using proper RS232 voltage levels, the TX line is at +12V when idle and a "1" bit is transmitted as -12V.

It sort of looks like you're over-thinking this. Is the line going high for 293us almost the same as sending a single bit (the start bit) at 38400 baud? [Your Serial.Begin() does call for a stop bit so you can never send just an isolated bit.]

Hi Morgan, yes im having trouble thinking at all...so not sure over thinking ...hehe.
(brain injury put me 1/2 in wheelchair 10 yrs ago)

logic4 capture is more accurate than my words
Download link to it here http://sailabilitygc.org/download/Dynamic%20Shark%20controller_on_capture.zip

Software to read that file is here Logic analyzer software from Saleae

Im just working on the final few packets in that data stream (which is a 'turn on, wait for bootup, then turn off' sequence)

I found a USB power supply (over a battery or 12v plug pack) this way i wont accidentally fry my USB ports if i forget to disconnect the power before trying to upload a revised sketch.

Sketch i am working with at the moment

#define RXpin 4  // Shark wheelchair controller only seems to use this for on/off 
                 // Maybe its not actually an RX but only other data wire from Joystick to Controller

#define TXpin 1    // Arduino TXpin


void setup() {
  // put your setup code here, to run once:

  Serial.begin(38400, SERIAL_8E1);
  
  pinMode(RXpin, INPUT_PULLUP); // This data line is held high (but for trailing data lows) while joystick is on.
  // digitalWrite(RXpin, HIGH); I probally dont need this as its allready high ?
    
    // if powerOn();    // this is where the on/off switch may go ?  
    // else powerOff();
    
 
  digitalWrite(TXpin, HIGH); // drive TX pin high
  delayMicroseconds(293000);
  digitalWrite(TXpin, LOW); // drive TRX pin Low
  delayMicroseconds(10280);  // after this the data packets from Joystick to motor controller inside wheelchair begin.

}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.write(0x60);   // Start bit " ' "(0x60)   Address ?
  Serial.write(192);   // Data 1 "192"(0xC0)   Y axis data
  Serial.write(192);    // Data 2 "192"(0xC0)   X axis data
  Serial.write(255);    // Data 3 "255"(0xFF)   Speed max setting
  Serial.write(192);    // Data 4 "192"(0xC0)   Speed fine tune ?
  Serial.write(128);    // Data 5 "128"(0x80)   Horn off/ 130on
  Serial.write(140);    // Data 6 "140"(0x8C)   Joystick on ?
  Serial.write(128);    // Data 7 "128"(0x80)   Chair mode (128drive/129tilt)
  Serial.write(212);    // Data 8 "212"(0xD4)   Some other XY modifier ?
  Serial.write(0x0F);    // End bit "15"(0x0F)   End packet

  //Delay next idle packet 17ms till next idle sent if no input from Shark joystick
  delay(17);
}

I think ill change it over to software serial, at least that way i can use the IDE's serial monitor.

The signal is inverted and i think its holding the line high when it needs to be low.

ie, low between packets, pulses high.

Other line pulses low at the trailing edge of each bit on TX line.

What should i be calling the other line...its not a clock. Maybe its the wheelchairs controllers TX line.

I have simplified the sketch, i was missing some {} ...i think and something to trigger the data capture.

// This sketch is to emulate the packet of data that the Shark Joystick sends


int trigger = 3; // this is used to trigger capture on the Logic4 conneced to hardware serial pins 0 & 1


void setup() {
    pinMode(trigger, OUTPUT); // set trigger to output
    digitalWrite(trigger, HIGH); // grounding this pin sets off the capture (in theory)
    delay(1000);
    digitalWrite(trigger, LOW); //this will triger capture.
    
    Serial.begin(38400, SERIAL_8E1);
  while (!Serial) {
    ; // wait for serial port to connect. 
  }
}
void loop() {
  // the brackets above and below are for the packet of data
  // below is the packet of data i would like to test there are notes next to what the
  // current thinking is as to the function of each piece of data
  // Logic4 Async serial inverterd logic sniffer is attached to pins
  //  RX and TX on Arduino Nano V3.0 and D3 which is just for triggering the data capture.

  {
    Serial.write(0x60);   // Start bit " ' "(0x60)   Address ?
    Serial.write(192);   // Data 1 "192"(0xC0)   Y axis data
    Serial.write(192);    // Data 2 "192"(0xC0)   X axis data
    Serial.write(255);    // Data 3 "255"(0xFF)   Speed max setting
    Serial.write(192);    // Data 4 "192"(0xC0)   Speed fine tune ?
    Serial.write(128);    // Data 5 "128"(0x80)   Horn off/ 130on
    Serial.write(140);    // Data 6 "140"(0x8C)   Joystick on ?
    Serial.write(128);    // Data 7 "128"(0x80)   Chair mode (128drive/129tilt)
    Serial.write(212);    // Data 8 "212"(0xD4)   Some other XY modifier ?
    Serial.write(0x0F);    // End bit "15"(0x0F)   End packet
  }
  //Delay next idle packet 17ms till next idle sent if no input from Shark joystick
  delay(1000);    //delay one second before resending same packet
}

Going to keep with Hardware serial, speed looks like its to high for software at 38400

Original settings for data capture are

Output of test sketch is below using same settings.

Decoded Protocol Result
‘250’ (0xFA)
‘252’ (0xFC)
‘4’ (0x04) (framing error)
‘252’ (0xFC)
‘206’ (0xCE)
‘254’ (0xFE)
‘174’ (0xAE) (framing error)
x (0x78) (framing error)

…which is only 8 not the 10 it should be,
also not right data.
serial protocol setting must be wrong ?

"High when idle" and "inverted" probably means that you are looking at a real RS232 data line. You need a MAX232 chip to convert the Arduino TTL levels to RS232 levels.

Your protocol analyzer settings don't match your Serial.begin(38400, SERIAL_8E1); The default for serial comms, and the most popular setting by far, is 8N1. If the thing was actually sending a parity bit (the "E") then you would have more bits sent over the wire and the analyzer with the "N" setting would be getting confused and possibly dropping bytes, giving you the wrong number of bytes received.

The Jazzy wheelchair Joystick insides picture

The communication i am trying to emulate is from an ATmega8.

As per http://gizmosmith.com/?p=586 ,
i have been able to capture the data from the Original
Dynamic Shark PowerChair Joystick (this is the chair i use daily so its back together now)

In reading the Hardware Serial output of the Arduino Nano v3.0,
i used the same settings (used on the capture of the ATmega8)
to 'see' the output and compare it to the original.

The signal is inverted as per the capture settings, maybe i need to learn how to invert the signals from an Arduino nano...

Anyone know how to do that ? or a link to an article i may read

Erik over at AVR freaks describes it as "pseudo-RS232"

Maybe once i invert the signal out of the Nano, it will match the code from the ATmega8 . The picture of the board above has lots of other parts, maybe its done with external parts too as i have seen some places theorized.

The MAX232 is an inverter.

SoftwareSerial does have an inverted option, although it's mainly used for receiving when you don't have a MAX232 and you don't need to transmit.

Found

SoftwareSerial sonarSerial(rxPin, txPin, true); //define serial port for recieving data, output from maxSonar is inverted requiring true to be set.

Now looking for more info on SoftwareSerial.h tho using the same settings as per

May get me what i need (i am no adverse to buying a MAX232 chip but dont have one atm)

Its worth a shot.

Oooo NewSoftSerial | Arduiniana , software inversion information.

I guess i am going over to software serial.

Time to do more reading.

Ill try the Arduino - SoftwareSerialConstructor

Out later and see if it pans out.

some level of success,

Regardless of ASII or HEX in the value fields it still prints `ÀÀÿÀ€Œ€Ô (last bit is not able to be seen for some reason but its a square with 000F inside it) well thats how it looks in the serial monitor , first and last bits are the only right ones…

Maybe it will look better with logic Analyzer

I’m getting closer at least its 10 per packet this time.

For anyone new to this thread, this is what i am trying to write each packet of data.
{
Serial.write(0x60); // Start bit " ’ "(0x60) Address ?
Serial.write(0xC0); // Data 1 “192”(0xC0) Y axis data
Serial.write(0xC0); // Data 2 “192”(0xC0) X axis data
Serial.write(0xFF); // Data 3 “255”(0xFF) Speed max setting
Serial.write(0xC0); // Data 4 “192”(0xC0) Speed fine tune ?
Serial.write(0X80); // Data 5 “128”(0x80) Horn off/ 130on
Serial.write(0x8C); // Data 6 “140”(0x8C) Joystick on ?
Serial.write(0x80); // Data 7 “128”(0x80) Chair mode (128drive/129tilt)
Serial.write(0xD4); // Data 8 “212”(0xD4) Some other XY modifier ?
Serial.write(0x0F); // End bit “15”(0x0F) End packet
}

one step closer…now getting a string as i wanted on the serial monitor, still to test with Logic4

Changed from Serial.write to Serial.print…all but for the first bit, that one is still Serial.write or it prints a DEC instead

This is the output - `19219225519212814012821215

// This sketch is to emulate the packet of data that the Shark Joystick sends
// Grounding the serial pin to start capture.


#include <SoftwareSerial.h>

#define txPin 3                                            //define pins used for software serial for Dynamic Shark Power chair controller
#define rxPin 2

//define serial port for transmitting data, output to Shark motor contoller must be inverted, requiring true to be set.
SoftwareSerial sharkSerial(rxPin, txPin, true);



void setup()
{
  Serial.begin(38400);                                      //start serial port for display
  sharkSerial.begin(38400);                                 //start serial port for maxSonar
  delay(500);                                              //wait for everything to initialize

}

void loop() {
  // the brackets above and below are for the packet of data
  // below is the packet of data i would like to test there are notes next to what the
  // current thinking is as to the function of each piece of data
  // Logic4 Async serial inverted logic sniffer is attached to pins
  //  RX and TX on Arduino Nano V3.0
  
    Serial.write(0x60);  // Start bit " ' "(0x60)   Address ?
    Serial.print(192);   // Data 1 "192"(0xC0)   Y axis data
    Serial.print(0xC0);    // Data 2 "192"(0xC0)   X axis data
    Serial.print(0xFF);    // Data 3 "255"(0xFF)   Speed max setting
    Serial.print(0xC0);    // Data 4 "192"(0xC0)   Speed fine tune ?
    Serial.print(0X80);    // Data 5 "128"(0x80)   Horn off/ 130on
    Serial.print(0x8C);    // Data 6 "140"(0x8C)   Joystick on ?
    Serial.print(0x80);    // Data 7 "128"(0x80)   Chair mode (128drive/129tilt)
    Serial.print(0xD4);    // Data 8 "212"(0xD4)   Some other XY modifier ?
    Serial.print(0x0F);    // End bit "15"(0x0F)   End packet
  
  //Delay next idle packet 17ms till next idle sent if no input from Shark joystick
  delay(1000);    //delay one second before re-sending same packet
}