RF Link Receiver & Transmitter from SparkFun

Picked up a couple of RF Link Transmitters and Receivers from Sparkfun, links below.

Transmitter Receiver

The problem is I am having a hell of a time getting them to work. I have two Arduino UNOs, both RF Link devices are wired as they should be, and I am following the instructions at this link that is on the SparkFun item page.

The instructions show that i should have the TX and RX pins on each Arduino connected to the proper pins on the RF Links. TX to the Data Input of the Transmitter, and RX to the Data Out of the Receiver. I make sure to have them unplugged before I upload the sketch, then plug those pins back in.

I have also tested all of the power and ground pins, wires, jumpers, etc, to make sure they are all working, and they are.

When I run the code on both arduinos, however, all I get from the Receiver's Serial Monitor window is a long list of zeros, even though the Transmitter should be sending an incrementing series of bytes (as evident in the Arduino code from the instructions link i posted above).

I also tried some VirtualWire code that I found here and there, but was unable to get anything useful out of it.

Anyone have any suggestions?

Anyone have any suggestions?

The usual one. Post your code.

Straight from the PDF i linked...

Transmitter

/*
* Simple Transmitter Code
* This code simply counts up to 255
* over and over
* (TX out of Arduino is Digital Pin 1)
*/
byte counter;
void setup(){
//2400 baud for the 434 model
Serial.begin(2400);
counter = 0;
}
void loop(){
//send out to transmitter
Serial.print(counter);
counter++;
delay(10);
}

Receiver

/*
* Simple Receiver Code
* (TX out of Arduino is Digital Pin 1)
* (RX into Arduino is Digital Pin 0)
*/
int incomingByte = 0;
void setup(){
//2400 baud for the 434 model
Serial.begin(2400);
}
void loop(){
// read in values, debug to computer
if (Serial.available() > 0) {
incomingByte = Serial.read();
Serial.println(incomingByte, DEC);
}
incomingByte = 0;
}

This code works perfectly fine when I connect the Arduinos together via a physical set of wires (one going between transmitters TX and receivers RX ports, the other joining grounds). But it doesn't work when I connect the RF Links to each arduino.

Transmitter is connected properly GRD, TX (digital pin 1), VCC (5V on Arduino). I have tried with an antenna and without.

Receiver has 8 pins. 3 GND, 1 Data Out (connected to RX), 1 Linear Out (unused or grounded), and 2 VCC (5V on Arduino), Again, antenna is optional.

Again, antenna is optional.

No, it isn't. The length defines the range. 0 length is pretty short range.

If the radios are on the serial pins, how are you seeing anything on the serial monitor?

Perhaps using NewSoftSerial to send/read the radio data would be a better idea.

Perhaps VirtualWire would be better, and not going thru the UART pins:

"VirtualWire is an Arduino library that provides features to send short messages, without addressing, retransmit or acknowledgment, a bit like UDP over wireless, using ASK (amplitude shift keying). Supports a number of inexpensive radio transmitters and receivers. All that is required is transmit data, receive data and (for transmitters, optionally) a PTT transmitter enable.

Does not use the Arduino UART. Messages are sent with a training preamble, message length and checksum. Messages are sent with 4-to-6 bit encoding for good DC balance, and a CRC checksum for message integrity.

Why not just use the Arduino UART connected directly to the transmitter/receiver? As discussed in the RFM documentation, ASK receivers require a burst of training pulses to synchronize the transmitter and receiver, and also requires good balance between 0s and 1s in the message stream in order to maintain the DC balance of the message. UARTs do not provide these. They work a bit with ASK wireless, but not as well as this code."

http://www.open.com.au/mikem/arduino/VirtualWire.pdf

well, i hacked around with the code for awhile and was able to get it to work. I am still using the TX and RX pins on the two arduinos, switched to 4800bps, and was able to get the transmitter to properly send a series of bytes to the receiver.

I tried the default Transmitter and Receiver code from the library, but was unable to get it to work, however this was before I got the straight serial data to work, so I may have a go at it again.

As of right now I am looping a dummy byte 10 times to make sure the send and receive are ready, then I send over a sync byte, transmitter ID byte, receiver ID byte, a command byte, and a checksum byte that is the added value of transID, receiverID and command bytes.

Only issue i am seeing right now is that the receiver seems to hang every 18-20 seconds, then un-hang 5-8 seconds after that. I am currently using a photo-interrupter on the transmitter to be the triggering device. When unobstructed, the transmitter sends the LED ON command, which the receiver picks up and turns an LED on. When obstructed, it sends the command to turn the LED off. Since the receiver hangs at those intervals, if it hangs when the LED is on or off, the LED will stay in that state until the hang is over.

Here is the code so far…

Transmitter

const byte dummyByte = B01010101;   // 85
const byte syncByte = B10101010;    // 170
const byte transID = B00000001;     // 1
const byte recievID = B00000001;    // 1
const byte ledon = B00001111;       // 15
const byte ledoff = B00001110;      // 14

boolean ledstatus = false;

void setup() {
  Serial.begin(4800);
  pinMode(A5,INPUT);
  pinMode(13,OUTPUT);
}

void loop() {
    check_photoint_status();
}
void check_photoint_status() {
  if ( analogRead(A5) < 500 && ledstatus == false ) {
      for (int i=0;i<10;i++){
        Serial.print(dummyByte);
      }
      Serial.print(syncByte);
      Serial.print(transID);
      Serial.print(recievID);
      Serial.print(ledon);
      Serial.print(transID+recievID+ledon, BYTE);
      digitalWrite(13,HIGH);
      ledstatus = true;
    } else if ( analogRead(A5) > 500 && ledstatus == true) {
      for (int i=0;i<10;i++){
        Serial.print(dummyByte);
      }
      Serial.print(syncByte);
      Serial.print(transID);
      Serial.print(recievID);
      Serial.print(ledoff);
      Serial.print(transID+recievID+ledoff, BYTE);
      digitalWrite(13,LOW);
      ledstatus = false;
    }
}

Receiver

int incomingByte = 0;

void setup(){
Serial.begin(4800);
pinMode(13,OUTPUT);
}

void loop(){
  if (Serial.available() > 0) {
    incomingByte = Serial.read();
    if (incomingByte == 170) {
      int transmitterID = (int)Serial.read();
      int receiverID = (int)Serial.read();
      int commandByte = (int)Serial.read();
      int checksumByte = (int)Serial.read();
      if (checksumByte == (transmitterID + receiverID + commandByte)) {
        if (commandByte == 14) {
          digitalWrite(13, LOW);
        } else if (commandByte == 15) {
          digitalWrite(13, HIGH);
        }
      }
    }
  } else {  }
  incomingByte = 0;
}

You don’t check that there is additional data available to be read after the first 170, so you may be getting some junk that is fouling your logic up.

if (incomingByte == 170) { <<< how do you know you have data ready to be read here?
int transmitterID = (int)Serial.read();
int receiverID = (int)Serial.read();
int commandByte = (int)Serial.read();
int checksumByte = (int)Serial.read();

I don't, which is why the next 3 bytes are added and compaired to the 4th, checksum byte. If the checksum byte is equal to the previous 3 bytes, then it would be considered valid. At least that's how it worked in the code.

I have since went back to the VirtualWire code. After reading that PDF you gave me, I realized the pins I was using was incorrect. I also found that I needed a thicker antenna wire with the VirtualWire method, but that isn't a problem at all.

The VirtualWire transmitter and receiver code in the examples included with the library take CHAR array and sends it as uint8_t. I am unsure how to easily combine them back into a string that I can compare with another string, such as...

if (var == "string")

the receiver code appears to simply step thru each item in the resulting buf[] via a FOR loop. Is there a easier way to take the array and just make it a solid String?

"I needed a thicker antenna wire with the VirtualWire method,"

Really? I use 30 guage wirewrap wire, works just fine.

On my receive end, the characters come in from 16 key keypad: '0', '1', '2', ... '9', 'A', 'B','C','D','#','*' I act on each one since I only send one at a time. I know there are ways to append received characters to a string, have not done so myself tho.

This reference page seems to go into decent details on that. http://arduino.cc/en/Reference/StringObject

okay, so I now have communication working perfectly, no major or minor delays in sending the signal from one Uno to the other. I have also set up the Transmitter Uno to go into sleep mode, then wake up when the PhotoResistor is unobstructed, pop the RF packet off for the Receiver to pick up. The receiver then triggers a chime module I picked up a RadioShack.

I haven't done a full test yet to see how long the batteries on the Transmitter will last (I am using 4x AA batters in series).

A couple questions:

1: would it be better to have the Transmitting Uno be powered by the battery, then have the Uno supply power to the PhotoResistor and RF Transmitter module, or instead to have the PhotoResistor be powered parallel to the Uno?

2: The DATA-OUT on the RF Receiver module on the other Uno, when not being sent a deliberate packet of data, just registers random noise. Would it be possible to split this signal off so that the Receiving Uno can make use of the data, and the secondary signal could trigger the Receiving Uno to wake from it's own Sleep function? I am assuming I would need a long enough packet (or multiple packets) to wake the receiving Uno and still give time for it to pick up the correct data packet. I cannot really use FALLING or RISING, since the normal RF data is random noise, so I assume against that I'd need to craft a wake up packet that either pushes DATA-OUT to be HIGH or LOW.

  1. With 4 AAs, you could add a series diode to bring the 6V to a little less (5.3?) and supply power to the 5V pin and all the other parts as well.

  2. You could try running the Rx thru a 100nF cap to one of the hardware interrupt pins (D2, INT0, or D3, INT1) with internal pullup enabled, see if a low bit coming in will cause an interrupt to wake up with.

If you are going to work with radios then it is worthwhile learning something about resonant antennas. You will not get much range the way you are now and a bit of metal between the devices could interfere or a transmitter elsewhere might obliterate it entirely. You can also do damage to the transmitter module if you put top voltage on it with no antenna.

Below is a comment from the website you mentioned in your post

I got the 315mHz transmitter/receiver pairs to work without difficulty, running from and to PICAXE 08M and 14M microprocessors. I used 23.8cm straight wire antennas on each. I'm glad the 315mHz version is available--I tried 433mHz and found that I am totally swamped in that frequency. Apparently 433mHz is in or very close to a legal ham range in the U.S. which can transmit at hundreds of times the power.

On 433 MHz I used about 170 mm -17cm See a picture here http://forums.adafruit.com/viewtopic.php?f=25&t=13122

Hi macharborguy,

I've similar project than you but over Xbee. I've several remote devices (up to 10) which are sending information to the receiver. I made the following code which is working more or less.

I've 2 issues: - inside the message transmitted, it can happen than the bytes for sync appear. It means that I loose the sync, and I can have strange behaviour of my software. I don't know how to fix. I'm looking for a way to use xmodem protocol or other but it was coded for Arduino. - I'm thinking also to use CRC control. If the checksum is wrong, I cancel the all the message.

Now I'm looking how to code CRC in my software.

How is your code today? Did you succeed?

Dear all, please find an update of my code. It’s more clever now.

// CENTRAL RECEIVER DEVICE

// INITIALISATION PARAMETERS
int populationDev = 2; // number of device in the network
int MetroTime = 350; // time between each packet

// incoming byte definition
// 200 = prior to remote device 0
// 201 = prior to remote device 1
// 202 = prior to remote device 2
// 203 = prior to remote device 3
// ...
// 209 = prior to remote device 9
// 249 = prior to packet
// 250 = prior to CRC16
// 251 = prior to the byte for measuring connection qualiity
// 252 = prior to message
// 253 = ending the message
// 254 = ending the packet
// 255 = empty byte

// connection quality measure with remote devices: timers
unsigned long timeMax = MetroTime * populationDev;
unsigned long timeDev[] = { 
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255 };
// connection quality measure with each remote device: previous value from error counter
unsigned long qualiPrev[] = { 
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255 };
// connection quality measure with each remote device: error counter
unsigned long qualiScore[] = { 
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255 };
// connection quality measure with each remote device: score in perthousand
int qualiScorePercent[] = { 
  (int) 0, (int) 0, (int) 0, (int) 0, (int) 0, (int) 0, (int) 0, (int) 0, (int) 0, (int) 0 };
// connection quality measure with each remote device: number of power cuts
int powerCut[] = { 
  (int) 0, (int) 0, (int) 0, (int) 0, (int) 0, (int) 0, (int) 0, (int) 0, (int) 0, (int) 0 };

// incoming packets for each transmitter
int PacketSize = 8;
byte inPacketPrev[] = { 
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255 };
byte inPacket[] = { 
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255,
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255 };

// menu byte
int menu = 255;

// byte incoming
byte inByte0 = 255;
byte inByte1 = 255;
byte inByte2 = 255;
int Dev = 255;

// initialize the LCD library with the numbers of the interface pins
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);

void setup() {
  // set up the LCD's number of columns and rows
  lcd.begin(20, 4);
  Serial.begin(9600);
}

// CRC16 calculation function
word crc16modbus() {
  word crc16 = 0xFFFF;
  for ( int a = 0 ; a <= PacketSize-1 ; a++ ){
    crc16 = crc16 ^ inPacketPrev[10*Dev+a];
    for ( int b = 1 ; b <= 8 ; b++ ){
      if (crc16 & 1){
        crc16 = (crc16 >> 1) ^ 0xA001;
      }
      else{
        crc16 = crc16 >> 1;
      }
    }
  }
  return crc16;
}

// XBee reading function
int inPacketRead( byte inByte0Funct, byte inByte1Funct, byte inByte2Funct ) {

  timeDev[Dev] = millis();
  inPacketPrev[10*Dev+0] = inPacket[10*Dev+0];
  inPacket[10*Dev+0] = inByte0Funct;
  inPacketPrev[10*Dev+1] = inPacket[10*Dev+1];
  inPacket[10*Dev+1] = inByte1Funct;
  inPacketPrev[10*Dev+2] = inPacket[10*Dev+2];
  inPacket[10*Dev+2] = inByte2Funct;
  Serial.print("Device "); // debug
  Serial.print(Dev, DEC); // debug
  Serial.println(": reading incoming bytes"); // debug
  for ( int a = 3 ; a <= PacketSize-1 ; a++ ) {
    inPacketPrev[10*Dev+a] = inPacket[10*Dev+a];
    inPacket[10*Dev+a] = Serial.read();
    lcd.setCursor(0 , 1); // debug 
    lcd.print(inPacket[10*Dev+a]); // debug 
  }
  if (crc16modbus() == inPacket[10*Dev+3] * 256 + inPacket[10*Dev+4]) {
    Serial.print("Device "); // debug
    Serial.print(Dev, DEC); // debug
    Serial.println(": CR16 is OK"); // debug
    return 1;
  }
  else {
    Serial.print("Device "); // debug
    Serial.print(Dev, DEC); // debug
    Serial.println(": CR16 is bad"); // debug
    return 0;
  }
}

// packet execution function
int inPacketExec() {

  int b = 0;
  unsigned long qualInt = 0;
  String inString = "";

  switch (inPacketPrev[10*Dev+2]) {
  case 251:
    // store the connection quality value (4 bytes)
    Serial.print("Device "); // debug
    Serial.print(inPacketPrev[10*Dev+1], DEC); // debug
    Serial.println(": store the connection bytes"); // debug

    for ( int a = 3 ; a <= PacketSize-1 ; a++ ) {
      if (inPacketPrev[10*Dev+a] != 253) {
        // best method to power by 2
        qualInt = qualInt + ( long(inPacketPrev[10*Dev+a]) * 1<<b );
        b = b + 8 ;
      }   
      else {
        break;
      }   
    }
    if (qualiPrev[Dev] == 255) {
      qualiPrev[Dev] = qualInt;
      qualiScore[Dev] = 0;
     }
    else {
      if ( qualInt < qualiPrev[Dev] ) {
        powerCut[Dev] = powerCut[Dev] + 1;
        qualiPrev[Dev] = 255;
        break;
      }
      else {
        qualiScore[Dev] = qualiScore[Dev] + qualInt - qualiPrev[Dev] - 1;
        qualiPrev[Dev] = qualInt;
        qualiScorePercent[Dev] = int( float( qualInt - qualiScore[Dev] ) / float(qualInt) * 1000);
      }  
    }
    break;
  case 252:
    // store the incoming message
    for ( int a = 3 ; a <= PacketSize-1 ; a++ ) {
      if (inPacketPrev[10*Dev+a] != 253) {
        inString.concat(char(inPacketPrev[10*Dev+a]));
      }   
      else   {
        break;
      }   
    }
    lcd.setCursor(2, 1);
    lcd.print("Dev ");
    lcd.setCursor(5, 1);
    lcd.print(Dev, DEC);
    lcd.setCursor(7 , 1);
    lcd.print("    ");  
    lcd.setCursor(7 , 1);
    lcd.print(inString);  
    break;
  }
}

// MAIN LOOP FUNCTION
void loop() {

  // menu browsing
  menu = 2; 

  // signal strength menu
  if (menu == 2) {
    lcd.setCursor(0, 0);
    lcd.print("Signal");
  }

  // Xbee packet reading & storing & CRC16 checking & packet execution
  inByte0 = Serial.read();
  if (inByte0 == 249) {
    inByte1 = Serial.read();
    if (inByte1 >= 200 && inByte1 <= 209) {
      inByte2 = Serial.read();
      if (inByte2 >= 250 && inByte2 <=252) {
        Dev = int(inByte1) - 200;
        if ( inPacketRead( inByte0, inByte1, inByte2 ) == 1 ) {
          inPacketExec() ;
        }
      }
    }
  }
  // print the connection status of each remote device
  for ( int a = 0 ; a <= 9 ; a++ ) {
    if (millis() >= timeDev[a] + populationDev * timeMax) {
      lcd.setCursor(10+a, 0);
      lcd.print("e");
    }
    else {
      lcd.setCursor(10+a, 0);
      lcd.print(a);
    }
  }
  // print connection quality indicators of each remote device
  for ( int a = 0 ; a <= 4 ; a++ ) {
    lcd.setCursor(a*4, 2);
    lcd.print("    ");
    lcd.setCursor(a*4, 2);
    lcd.print(qualiScorePercent[a]);
  }
  for ( int a = 5 ; a <= 9 ; a++ ) {
    lcd.setCursor((a-5)*4, 3);
    lcd.print("    ");
    lcd.setCursor((a-5)*4, 3);
    lcd.print(qualiScorePercent[a]);
  }
  // print the number of power cuts of each remote device
  for ( int a = 0 ; a <= 4 ; a++ ) { // to move in the lcd and to increase up to 9
    lcd.setCursor(12+2*a, 2);
    lcd.print(powerCut[a]);
  }
}
// REMOTE TRANSMITTER

// INITIALISATION PARAMETERS
byte Dev = 201; // device ID
int populationDev = 2; // number of device in the network
int MetroTime = 350; // time between each packet

// packet
int PacketSize = 8;
byte outPacket[] = { 
  (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255, (byte) 255 };

// connection speed regulation
#include <Metro.h> // lib to not use delay() function = to not freeze the Arduino
Metro waitAndSendMetro = Metro(MetroTime * populationDev); 

// others
int z = 65; // debug ASCII counting
unsigned long i = 0;
//unsigned long i = 2147483600; // debug
word crc16;

void setup()
{
  Serial.begin(9600);
  //delay(2000);
}

// CRC16 code
word crc16modbus(byte msg[]){
  word crc16 = 0xFFFF;
  for ( int a = 0 ; a <= PacketSize-1 ; a++ ){
    crc16 = crc16 ^ msg[a];
    for ( int b = 1 ; b <= 8 ; b++ ){
      if (crc16 & 1){
        crc16 = (crc16 >> 1) ^ 0xA001;
      }
      else{
        crc16 = crc16 >> 1;
      }
    }
  }
  return crc16;
}

void loop()
{
  // connection quality packet transmission
  if (waitAndSendMetro.check() == 1) {
    i++;
    Serial.println(" "); // debug
    Serial.println(i, DEC); // debug
    outPacket[0] = byte(249); // prior to packet
    outPacket[1] = byte(Dev); // device byte
    outPacket[2] = byte(251); // prior to test bytes
    outPacket[6] = byte(int( i/256/256/256) );
    outPacket[5] = byte(int( (i-outPacket[6]*256*256*256) /256/256) );
    outPacket[4] = byte(int( (i-outPacket[5]*256*256) /256) );
    outPacket[3] = byte(int( i-outPacket[4]*256) );
    //outPacket[3] = byte(1); // debug
    //outPacket[4] = byte(2); // debug
    //outPacket[5] = byte(3); // debug
    //outPacket[6] = byte(4); // debug
    outPacket[7] = byte(253); // ending byte
    for ( int a = 0 ; a <= PacketSize-1 ; a++ ) {
      Serial.print(outPacket[a], BYTE);
    }
    // CRC16 packet transmission
    crc16 = crc16modbus(outPacket);
    outPacket[0] = byte(249); // prior to packet
    outPacket[1] = byte(Dev); // device byte
    outPacket[2] = byte(250); // prior to CRC16 word
    outPacket[3] = byte(int(crc16/256));
    outPacket[4] = byte(crc16 - outPacket[3] * 256);
    outPacket[5] = byte(253); // ending byte
    outPacket[6] = byte(255);
    outPacket[7] = byte(255);
    for ( int a = 0 ; a <= PacketSize-1 ; a++ ) {
      Serial.print(outPacket[a], BYTE);
    }
  }

  // message transmission
  if (waitAndSendMetro.check() == 1) {
    outPacket[0] = byte(249); // prior to packet
    outPacket[1] = byte(Dev); // device byte
    outPacket[2] = byte(252); // prior to message

    // debug
    switch (Dev) {
    case 200:    
      outPacket[3] = byte('A');
      outPacket[4] = byte('B');
      outPacket[5] = byte('C');
      if ( z >= 90) {
        z = 64;
      }
      z++;
      outPacket[6] = byte(char(z));
      outPacket[7] = byte(253); // ending byte
      break;
    case 201:
      outPacket[3] = byte('1');
      outPacket[4] = byte('2');
      if ( z >= 90) {
        z = 64;
      }
      z++;
      outPacket[5] = byte(char(z));
      outPacket[6] = byte(253); // ending byte
      outPacket[7] = byte(255);
      break;
    }   
    // end debug

    for ( int a = 0 ; a <= PacketSize-1 ; a++ ) {
      Serial.print(outPacket[a], BYTE);
    }
    // CRC16 packet transmission
    crc16 = crc16modbus(outPacket);
    outPacket[0] = byte(249); // prior to packet
    outPacket[1] = byte(Dev); // device byte
    outPacket[2] = byte(250); // prior to CRC16 word
    outPacket[3] = int(crc16/256);
    outPacket[4] = crc16 - outPacket[3] * 256;
    outPacket[5] = byte(253); // ending byte
    outPacket[6] = byte(255);
    outPacket[7] = byte(255);
    for ( int a = 0 ; a <= PacketSize-1 ; a++ ) {
      Serial.print(outPacket[a], BYTE);
    }
  }
}