User Tools

Site Tools


arduino:wio-rascii-en

Differences

This shows you the differences between two versions of the page.


Previous revision
arduino:wio-rascii-en [2025/05/04 07:17] (current) – [Frame] rjversluis
Line 1: Line 1:
 +======WIO RASCII======
 +
 +|  //Not to be translated.//  |
 +
 +RASCII documentation as used in WIO.\\
 +
 +^  WIP  ^
 +
 + \\
 +=====Overview=====
 +
 +====Frame====
 +|< >|
 +^  Header  ^^^|  Data  |
 +| Prefix | Length | OPC | NID | Data 0...120 |
 + \\
 +|< >|
 +^ Field ^ Description ^ Remark ^ Size ^
 +| Prefix | Message type | | 1 char |
 +| Length | OPC + NID + Data | | 2 char |
 +| OPC | Operation Code | Command/Event | 2 char |
 +| NID | Node ID | 0...255, zero is broadcast | 2 char |
 +| Data | Optional data |  | 0, 2, 4, ...240 char |
 +
 +
 + \\
 +====Binary Structure====
 +|< >|
 +^ Field ^ Value ^ Size |
 +| type | Prefix character | char |
 +| nid  | bin(NID) | byte |
 +| opc  | bin(OPC) | byte |
 +| dlc  | (bin(Length)/2) - 2 | byte |
 +| data[120] | Data bin(0)...bin(120) | byte[120] |
 +
 + \\
 +====Example====
 +RASCII:
 +<code>
 +$060C2101
 +</code>
 +Binary:
 +<code>
 +type=$
 +nid=31 (0x21)
 +opc=12 (0x0C)
 +dlc=1  (6/2 - 2)
 +data[0]=1
 +</code>
 +
 + \\
 +
 +=====Constants=====
 +====Prefixes====
 +<code>
 +#define PREFIX_CMD '@'
 +#define PREFIX_EVT '$'
 +#define PREFIX_INF '#'
 +#define PREFIX_RSP '&'
 +#define PREFIX_TXT '/'
 +</code>
 +
 +====Commands====
 +<code>
 +#define CMD_INFO        0
 +#define CMD_START       1
 +#define CMD_STOP        2
 +#define CMD_GETCONF     3
 +#define CMD_SETCONF     4
 +#define CMD_RESETCONF   5
 +#define CMD_GETCV       6
 +#define CMD_SETCV       7
 +#define CMD_DOUT        10
 +#define CMD_AOUT        11
 +#define CMD_ACCESSORY   12
 +#define CMD_MOBILE_DIRV 13
 +#define CMD_MOBILE_FUN  14
 +#define CMD_MOBILE_DISPATCH 15
 +#define CMD_MOBILE_RELEASE  16
 +#define CMD_EBREAK          17
 +#define CMD_SOD             18
 +#define CMD_QUERY           19
 +#define CMD_SETIDTYPE       20
 +#define CMD_SETWIO          21
 +
 +#define CMD_SERVO           23
 +#define CMD_TEXT            24
 +#define CMD_CLOCK           25
 +#define CMD_SIGNAL          26
 +#define CMD_SWITCH          27
 +#define CMD_BINSTATE        28
 +#define CMD_MOBILE_SHORTID  29
 +#define CMD_CLEAR_SHORTIDS  30
 +#define CMD_END_SHORTIDS    31
 +#define CMD_SHUTDOWN        32
 +#define CMD_MOBILE_STATE    33
 +#define CMD_SOUND_PLAY      34
 +#define CMD_OTA             35
 +#define CMD_REBOOT          36
 +#define CMD_PT_ON           37
 +#define CMD_PT_OFF          38
 +
 +</code>
 +
 +====Events====
 +<code>
 +#define EVT_ALIVE 0
 +#define EVT_OCC   1
 +#define EVT_RFID  2
 +#define EVT_DIN   3
 +#define EVT_AIN   4
 +#define EVT_DSEN  5
 +#define EVT_ASEN  6
 +#define EVT_DOUT  7
 +#define EVT_ACCESSORY    8
 +#define EVT_SHORTCIRCUIT 9
 +#define EVT_BIDI         10
 +#define EVT_SENSORID     11
 +#define EVT_STATE        12
 +#define EVT_MOBILE_STATE 13
 +#define EVT_GOODBYE      255
 +</code>
 +
 +====BiDi type====
 +<code>
 +#define BIDI_SETCV   0 // POM
 +#define BIDI_GETCV   1 // POM
 +#define BIDI_ADDRESS 2
 +#define BIDI_DYN     3
 +#define BIDI_EXT     4
 +</code>
 +
 +====Port type====
 +<code>
 +#define PORTTYPE_DOUT  0
 +#define PORTTYPE_AOUT  1
 +#define PORTTYPE_SERVO 2
 +</code>
 +
 + 
 + \\
 +=====System=====
 +====Commands====
 +^ Prefix ^ Length ^ Code ^ Data ^ Example ^ Description ^
 +| PREFIX_CMD | 4 | CMD_START | - | "@040100" | Global track power ON |
 +| PREFIX_CMD | 4 | CMD_STOP | - | "@040200" | Global track power OFF |
 +| PREFIX_CMD | 4 | CMD_EBREAK | - | "@041100" | Emergency break |
 +| PREFIX_CMD | 4 | CMD_SOD | - | "@041200" | Start of Day |
 +| PREFIX_CMD | 4 | CMD_CLEAR_SHORTIDS | - | "@041E00" | All WIO Controls should clear the locomotive list |
 +| PREFIX_CMD | 4 | CMD_END_SHORTIDS | - | "@041F00" | End of new short ID broadcasting |
 +| PREFIX_CMD | 4 | CMD_SHUTDOWN | - | "@042000" | Shutdown |
 +====Events====
 +^ Prefix ^ Length ^ Code ^ Data ^ Example ^ Description ^
 +| PREFIX_EVT | 6...22 | EVT_STATE | D0=state flags (0x01=globalpower), D1+D2=boosterID, D3+D4=current, D5+D6=volt, D7+D8=temp | "$060Cnn01" | Global track power state event |
 +
 + \\
 +=====Mobile=====
 +====Commands====
 +^ Prefix ^ Length ^ Code ^ Data ^ Example ^ Description ^
 +| PREFIX_CMD | 10 + ID-length * 2 | CMD_MOBILE_SHORTID | D0=addrH, D1=addrL, D2=dirF, D3=speed D4="shortID" | "@121D0003800054657374" | Publish a short ID ("Test", addr=3, forwards, lights off and V0 in the example.) |
 +| PREFIX_CMD | 32 | CMD_MOBILE_DIRV | D0=bus, D1=addrH, D2=addrL, D3=dirV, D4=lights, D5=steps, D6=mass, D7=speed, D8=angle, D9=minstep, D10=maxstep, D11=throttleID, D12=automode, D13=pwmH, D14=pwmL | "@200D210003807F0A000005604D000000" | Direction and speed |
 +| PREFIX_CMD | 22 | CMD_MOBILE_FUN | D0=bus, D1=addrH, D2=addrL, D3=Fchanged, D4=on/off, D5=lights, D6...D9=fx, D10=throttleID | | One changed function and state of all 32. |
 +| PREFIX_CMD | 14 | CMD_BINSTATE | D0=bus, D1=addrH, D2=addrL, D3=binH, D4=binL, D5=state | | Change binary state for one port. |
 +| PREFIX_CMD | 16 | CMD_MOBILE_DISPATCH | D0=bus, D1=addrH, D2=addrL, D3=V, D4=Lights, D5=fxH, D6=fxL | | Dispatch loco for throttle. |
 +| PREFIX_CMD | 8 | CMD_MOBILE_RELEASE | D0=bus, D1=addrH, D2=addrL | | Release loco from throttle. |
 +
 + \\
 +
 +
 +=====Signal=====
 +====Commands====
 +^ Prefix ^ Length ^ Code ^ Data ^ Example ^ Description ^
 +| PREFIX_CMD | 18 | CMD_SIGNAL | D0=bus, D1=addr, D2=nraspects, D3=aspect, D4=valueH, D5=valueL, D6=brightness, D7=dim | "@121A010403020007FF99" | Set signal aspect. |
 +
 +
 + \\
 +=====Switch=====
 +====Commands====
 +^ Prefix ^ Length ^ Code ^ Data ^ Example ^ Description ^
 +| PREFIX_CMD | 12 | CMD_SERVO | D0=bus, D1=addr, D2=paramon/off, D3=delay, D4=on/off |  | Type: Servo \\ Parameter range: 0...180° |
 +| PREFIX_CMD | 16 | CMD_SWITCH | D0=bus, D1=addrH, D2=addrL, D3=port, D4=gate, D5=value, D6=delay |  | Type: Accessory + DCC |
 +| PREFIX_CMD | 8 | CMD_ACCESSORY | D0=bus, D1=addr, D2=on/off |  | Type: None Servo + Single gate |
 +| PREFIX_CMD | 8 | CMD_ACCESSORY | D0=bus, D1=addr, D2=gate |  | Type: None Servo + no single gate |
 +
 +
 + \\
 +=====Output=====
 +====Commands====
 +^ Prefix ^ Length ^ Code ^ Data ^ Example ^ Description ^
 +| PREFIX_CMD | 12 | CMD_DOUT | D0=bus, D1=addr, D2=on, D3=delay, D4=blink |  | - |
 +| PREFIX_CMD | 12 | CMD_SERVO | D0=bus, D1=addr, D2=paramon/off, D3=delay, D4=on/off |  | Type: Servo |
 +| PREFIX_CMD | 6 + soundfile*2 | CMD_SOUND_PLAY | D0=bus, D1=paramon/off, D2...Dn=Soundfilename |  | Type: Sound |
 +| PREFIX_CMD | 18 | CMD_AOUT | D0=bus, D1=addr, D2=valueon, D3=red, D4=green, D5=blue, D6=blink+delay, D7=paramon |  | Type: LED + Color |
 +| PREFIX_CMD | 22 | CMD_MOTOR | D0=bus, D1=addr, D2=dirT, D3=delay, D4=stepsH, D5=stepsM, D6=stepsL, D7=reportH, D8=reportM, D9=reportL |  | Type: Motor \\ dirT&0x80=direction, dirT&0x40=calibrate, dirT&0x3F=cancel |
 +
 + \\
 +
 +
 +=====Text=====
 +====Commands====
 +^ Prefix ^ Length ^ Code ^ Data ^ Example ^ Description ^
 +| PREFIX_TXT | 6 + textlength*1 | CMD_TEXT | D0=bus, D1=display, D2...Dn=text |  | The text is __not__ in HEXA, max 250 length. |
 +
 + \\
 +
 +=====Clock=====
 +====Commands====
 +^ Prefix ^ Length ^ Code ^ Data ^ Example ^ Description ^
 +| PREFIX_CMD | 8 | CMD_CLOCK | D0=hour, D1=minute, D2=brightness |  |  |
 +
 +
 + \\
 +=====Program=====
 +====Commands====
 +^ Prefix ^ Length ^ Code ^ Data ^ Example ^ Description ^
 +| PREFIX_CMD | 2 | CMD_QUERY |  |  | Query all WIO modules. |
 +| PREFIX_CMD | 4 | CMD_OTA | D0=bus |  | Put a WIO module in OTA mode for firmware update. |
 +| PREFIX_CMD | 8 + nodename*2 | CMD_SETIDTYPE | D0=bus, D1=ID , D2=config, D3...Dn=nodename |  | D1 is the new WIO ID number, and config determines the WIO type. |
 +| PREFIX_CMD | 4 | CMD_REBOOT | D0=bus |  | Reboot the selected WIO module. |
 +| PREFIX_CMD | 16 + configlength*2 | CMD_SETWIO | D0=bus, D1=I/O-index, D2=pulselength, D3=option1, D4=options2, D5=steps, D6=deepsleep, D7...Dn=I/O-configstring |  | Configure the WIO module. |
 +| PREFIX_CMD | 12 | CMD_GETCV | D0=bus, D1=addrH, D2=addrL, D3=cvH, D4=cvL, D5=options |  | options: bit0=PT, bit1=accessory \\ Default POM Mobile.|
 +| PREFIX_CMD | 14 | CMD_SETCV | D0=bus, D1=addrH, D2=addrL, D3=cvH, D4=cvL, D5=value, D6=options |  |  |
 +
 +
 +====Responses====
 +^ Prefix ^ Length ^ Code ^ Data ^ Example ^ Description ^
 +| PREFIX_RSP | 42 | CMD_QUERY | D0=bus, D1=type, D2=manu, D3=pid, D4=vmaj, D5=vmin, D6=options1, D7=battery/load, D8=rssiH, D9=rssiL, D10=tempH, D11=tempL, D12=pressH, D13=pressL, D14=humH, D15=humL, D16=options2, D17=steps, D18=deepsleep, D19=pulse |  |  |
 +
 +
 + \\
 +=====Events=====
 +^ Prefix ^ Length ^ Code ^ Data ^ Example ^ Description ^
 +| PREFIX_EVT | 16 | EVT_GOODBYE | D0=bus, D1=analogH, D2=analogL, D3=rssiH, D4=rssiL, D5=locoH, D6=locoL |  | WIO Control in pause or low battery. |
 +| PREFIX_EVT | 6 | EVT_SHORTCIRCUIT | D0=bus, D1=shortcircuit |  | WIO Boost/Drive reports overload. |
 +| PREFIX_EVT | 32 | EVT_ALIVE | D0=bus, D1=analogH, D2=analogL, D3=rssiH, D4=rssiL, D5=locoH, D6=locoL, D7=tempH, D8=tempL, D9=temp100H, D10=temp100L, D11=pressH, D12=pressL, D13=humH, D14=humL |  |  |
 +| PREFIX_EVT | 8 | EVT_DIN | D0=bus, D1=port, D2=value |  | Digital input. |
 +| PREFIX_EVT | 8 | EVT_DOUT | D0=bus, D1=port, D2=value |  | Digital output. |
 +| PREFIX_EVT | 10 | EVT_ACCESSORY | D0=bus, D1=port, D2=value, D3=**[[#port_type|Port type]]** |  | In case of servo type the value is in degrees. |
 +| PREFIX_EVT | 16 | EVT_BIDI | D0=bus, D1=port, D2=locoH, D3=locoL, D4=**[[#bidi_type|BiDi type]]**, D5=index, D6=value |  |  |
 +| PREFIX_EVT | 8 + rfidlen*2 | EVT_RFID | D0=bus, D1=port, D2=len, D3...Dn=RFID |  | Stationary sensor; Must be confirmed. |
 +| PREFIX_EVT | 8 + rfidlen*2 | EVT_SENSORID | D0=bus, D1=port, D2=len, D3...Dn=RFID |  | Mobile sensor; Must be confirmed. |
 +
 +
 +
 + \\
 +=====C Code=====
 +<code c>
 +typedef struct RASCIIFrame {
 +  char type;
 +  byte opc;
 +  byte nid;
 +  byte dlc;
 +  byte data[120];
 +} *iRASCIIFrame;
 +
 +static byte _HEXA2Byte( const char* s ) {
 +  /*                    0  1  2  3  4  5  6  7  8  9  :  ;  <  =  >  ?  @  A           F */
 +  static char hexb[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15};
 +  return (hexb[s[0] - 0x30] << 4) + hexb[s[1] - 0x30];
 +}
 +
 +
 +static char* _Byte2HEXA(byte b, char* c) {
 +  static char cHex[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
 +  c[0] = cHex[(b&0xF0)>>4];
 +  c[1] = cHex[ b&0x0F    ];
 +  c[2] = '\0';
 +  return c;
 +}
 +
 +
 +static int _encode( iRASCIIFrame frame, char* rascii) {
 +  int idx = 0;
 +
 +  // Type @,#,$,&,/
 +  rascii[0] = frame->type;
 +  idx++;
 +
 +  if( frame->dlc > 120 ) {
 +    TraceOp.trc( "RASCII", TRCLEVEL_WARNING, __LINE__, 9999, "encode: invalid length of %d (max. 120)", frame->dlc );
 +    return -1;
 +  }
 +
 +  // Length = opc + rid + data
 +  _Byte2HEXA((frame->dlc + 1 + 1) * 2, rascii + idx);
 +  idx+=2;
 +
 +  // Command, Event
 +  _Byte2HEXA(frame->opc, rascii+idx);
 +  idx+=2;
 +
 +  // Recipioent ID
 +  _Byte2HEXA(frame->nid, rascii+idx);
 +  idx+=2;
 +
 +  // Data
 +  if( frame->dlc <= 120 ) {
 +    for( int i = 0; i < frame->dlc; i++ ) {
 +      _Byte2HEXA(frame->data[i], rascii+idx);
 +      idx+=2;
 +    }
 +  }
 +  rascii[idx+0] = '\n';
 +  rascii[idx+1] = '\0';
 +  idx++;
 +
 +  return idx;
 +}
 +
 +
 +static char _decode( const char* rascii, iRASCIIFrame frame ) {
 +  int idx = 0;
 +  frame->type = rascii[0];
 +  idx += 1;
 +  frame->dlc  = (RASCIIOp.HEXA2Byte(rascii+idx) / 2 );
 +
 +  if( frame->dlc < 2 ) {
 +    TraceOp.trc( "RASCII", TRCLEVEL_WARNING, __LINE__, 9999, "decode: invalid length of %d", frame->dlc );
 +    return '\0';
 +  }
 +  idx += 2;
 +
 +  frame->dlc -= 2; // dlc = len - opc - nid
 +
 +  if( frame->dlc > 120 ) {
 +    TraceOp.trc( "RASCII", TRCLEVEL_WARNING, __LINE__, 9999, "decode: invalid length of %d", frame->dlc );
 +    return '\0';
 +  }
 +
 +  frame->opc  = RASCIIOp.HEXA2Byte(rascii+idx);
 +  idx += 2;
 +  frame->nid  = RASCIIOp.HEXA2Byte(rascii+idx);
 +  idx += 2;
 +
 +  for( int i = 0; i < frame->dlc; i++ ) {
 +    frame->data[i] = RASCIIOp.HEXA2Byte(rascii + idx + (i * 2) );
 +  }
 +
 +  return rascii[0];
 +}
 +
 +
 +
 +#ifndef __RASCII_CODES_H__
 +#define __RASCII_CODES_H__
 +
 +#define PREFIX_CMD '@'
 +#define PREFIX_EVT '$'
 +#define PREFIX_INF '#'  // Text must be also escaped in HEXA.
 +#define PREFIX_RSP '&'
 +
 +#define CMD_INFO        0
 +#define CMD_START       1
 +#define CMD_STOP        2
 +#define CMD_GETCONF     3
 +#define CMD_SETCONF     4
 +#define CMD_RESETCONF   5
 +#define CMD_GETCV       6
 +#define CMD_SETCV       7
 +#define CMD_DOUT        10
 +#define CMD_AOUT        11
 +#define CMD_ACCESSORY   12
 +#define CMD_MOBILE_DIRV 13
 +#define CMD_MOBILE_FUN  14
 +#define CMD_MOBILE_DISPATCH 15
 +#define CMD_MOBILE_RELEASE  16
 +#define CMD_EBREAK          17
 +#define CMD_SOD             18
 +#define CMD_QUERY           19
 +#define CMD_SETIDTYPE       20
 +#define CMD_SETWIO          21
 +
 +#define CMD_SERVO           23
 +#define CMD_TEXT            24
 +#define CMD_CLOCK           25
 +#define CMD_SIGNAL          26
 +#define CMD_SWITCH          27
 +#define CMD_BINSTATE        28
 +#define CMD_MOBILE_SHORTID  29
 +#define CMD_CLEAR_SHORTIDS  30
 +#define CMD_END_SHORTIDS    31
 +#define CMD_SHUTDOWN        32
 +#define CMD_MOBILE_STATE    33
 +#define CMD_SOUND_PLAY      34
 +#define CMD_OTA             35
 +#define CMD_REBOOT          36
 +#define CMD_PT_ON           37
 +#define CMD_PT_OFF          38
 +#define CMD_ACC_GETCV       39
 +#define CMD_ACC_SETCV       40
 +#define CMD_ACC_PAIR        41
 +#define CMD_MOTOR           42
 +#define CMD_SLEEP           43
 +#define CMD_SHOW            44 // Identify by flashing LED(s)
 +#define CMD_STARTCAM        45
 +#define CMD_STOPCAM         46
 +
 +#define EVT_ALIVE 0
 +#define EVT_OCC   1
 +#define EVT_RFID  2
 +#define EVT_DIN   3
 +#define EVT_AIN   4
 +#define EVT_DSEN  5
 +#define EVT_ASEN  6
 +#define EVT_DOUT  7
 +#define EVT_ACCESSORY    8
 +#define EVT_SHORTCIRCUIT 9
 +#define EVT_BIDI         10
 +#define EVT_SENSORID     11
 +#define EVT_STATE        12
 +#define EVT_MOBILE_STATE 13
 +#define EVT_PT           14
 +#define EVT_IO           15
 +#define EVT_GOODBYE      255
 +
 +#define BIDI_SETCV   0 // POM
 +#define BIDI_GETCV   1 // POM
 +#define BIDI_ADDRESS 2
 +#define BIDI_DYN     3
 +#define BIDI_EXT     4
 +#define BIDI_PT      5
 +#define BIDI_SC      6 // Short circuit
 +
 +#define PROGOPT_PT     0x01
 +#define PROGOPT_ACC    0x02
 +#define PROGOPT_SET    0x04 // GET if not set
 +
 +#define PORTTYPE_DOUT  0
 +#define PORTTYPE_AOUT  1
 +#define PORTTYPE_SERVO 2
 +#define PORTTYPE_PAIR  3
 +#define PORTTYPE_MOTOR 4
 +#define PORTTYPE_DIN   5
 +#define PORTTYPE_ACC   6
 +#define PORTTYPE_LED   7
 +
 +#define STATEFLAG_POWER 0x01
 +
 +#define PORT_STATE_STRAIGHT 0
 +#define PORT_STATE_TURNOUT  1
 +
 +#define RFID_LENGTH_MASK  0x0F
 +#define RFID_STATE_OFF    0x80
 +#define RFID_STATE_ERROR  0x40
 +
 +#define SUBIOTYPE_NONE     0
 +#define SUBIOTYPE_LED      1
 +#define SUBIOTYPE_SERVO    2
 +#define SUBIOTYPE_RFID     3
 +#define SUBIOTYPE_DCC      4
 +#define SUBIOTYPE_MOBILE   5
 +#define SUBIOTYPE_CAM      6
 +#define SUBIOTYPE_CANBUS   7
 +#define SUBIOTYPE_THROTTLE 8
 +
 +#define MOBILE_STATE_LOWBATTERY 1
 +
 +
 +#endif
 +
 +
 +
 +
 +</code>
 +
 +
 +
 + \\
 +=====16bit NID=====
 +Proposal for 16bit NID:\\
 +If the first character of the NID is a ''~'' (Tilde) the following 4 characters will present the 16bit NID.\\
 +
 +
 +