Project

General

Profile

RS-232 serial cable replacement

Added by toddm over 4 years ago

Hi All,

I’m trying to get to the point where I can replace an RS-232 serial connection with a couple of RF_12B modules operated by Atmega328p uC running on the internal 8Mhz osc. The data I want to sending is basically Modbus RTU.

I have tried the rf12serial sketch and it does not seem to do anything with the longer Modbus packets. I can only get single characters across and then there are alot hickups in the the data, like the buffer is problematic. I am probably mis-using/mis-understanding what it is supposed to do.

I have cobbled together a few other sketches from various places trying to understand how the RF12 driver operates.

I used this sketch to transmit an indexing counter:

#include 
byte myId;              // remember my own node ID

void setup()
{
    Serial.begin(9600);
    rf12_initialize(1, RF12_915MHZ);
    Serial.print("\n[rfStrings]");
    myId = rf12_config();
}

unsigned long counter = 1000;

void loop ()
{
  ++counter;
  Serial.println(counter);
  rf12_sendNow(0, &counter, sizeof(counter));
  delay(500);
}

Then the sketch that does the RX and Display of the Counter value: It is basically the rf12packetbuf demo sketch with a few small changes to help me understand.

/// @dir packetBuf
/// This example shows how to fill a packet buffer with strings and send them.
// 2010-09-27  http://opensource.org/licenses/mit-license.php

// Note: this demo code sends with broadcasting, so each node will see data
// from every other node running this same sketch. The node ID's don't matter
// (they can even be the same!) but all the nodes have to be in the same group.
// Use the RF12demo sketch to initialize the band/group/nodeid in EEPROM.

#include 

/// Utility class to fill a buffer with string data.
class PacketBuffer : public Print {
public:
    PacketBuffer () : fill (0) {}

    const byte* buffer() { return buf; }
    byte length() { return fill; }
    void reset() { fill = 0; }

#if ARDUINO < 100
    virtual void write(uint8_t ch)
        { if (fill < sizeof buf) buf[fill++] = ch; }
#else
    virtual size_t write(uint8_t ch) {
        if (fill < sizeof buf) {
            buf[fill++] = ch;
            return 1;
        }
        return 0;
    }
#endif

private:
    byte fill, buf[RF12_MAXDATA];
};

byte myId;              // remember my own node ID
byte needToSend;        // set when we want to send
word counter;           // incremented each second
MilliTimer sendTimer;   // used to send once a second
PacketBuffer payload;   // temp buffer to send out

void setup () {
    Serial.begin(57600);
    Serial.print("\n[rfStrings]");
    myId = rf12_config();
}

void loop () {
    if (rf12_recvDone() && rf12_crc == 0) {
        // a packet has been received
        Serial.print("Length ");
        Serial.println(rf12_len);
//        for (byte i = 0; i < rf12_len; ++i)
        for (byte i = rf12_len; i > 0; --i)
            Serial.print(rf12_data[i]);
        Serial.println();
    }

    // we intend to send once a second
    if (sendTimer.poll(1000)) {
        needToSend = 1;
        ++counter;
        Serial.print(" SEND ");
        Serial.println(counter);
    }

    // can only send when the RF12 driver allows us to
    if (needToSend && rf12_canSend()) {
        needToSend = 0;
        // fill the packet buffer with text to send
        payload.print("myId = ");
        payload.print(myId, DEC);
        payload.print(", counter = ");
        payload.print(counter);
        payload.print(", millis = ");
        payload.print(millis());
        // send out the packet
        rf12_sendStart(0, payload.buffer(), payload.length());
        payload.reset();
    }
}

I connected both of the Arduinos with their RF12B’s to my pc through different USB to TTL cables. The sending sketch indexes a counter then broadcasts it over the Radio. The receiving sketch sends the received data to the connected COM port which I can see in the Arduino IDE Serial Monitor. The problem here is that the data bytes appear to be switched. If I start the counter at 1000 decimal it will get incremented by 1 then sent out as 1001 decimal. When the Receiving program prints to the serial port I get 233300 the next entry is 234300. If I let it run I see that it counts up to 255300 then the next entry is 0400. So it looks to me like the bytes are swapped. You can see my attempt to switch them in the rx code “for” loop, which didn’t work..

So, Is there a simpler way to go about sending packets across the radios to replace a cable? I can’t seem to get my head around it.

Thanks for any insight you may be able to provide!


Replies (1)

RE: RS-232 serial cable replacement - Added by toddm over 4 years ago

I found one problem. I had changed the Serial.write to a Serial.print in the “for” loop on the receiver side. Now I get an ASCII version of the Decimal value I send. I’m going to play around with the Packetbuf example and see if I can transfer multiple bytes of data the way i think I need to. Then I need to figure out how to get the Arduino code to handle the incoming Modbus packets.

Will I need to handle each byte of the Modbus command? Or can I just “pass” it along as a whole to the RF? sorry for the noob. questions.

Todd.

    (1-1/1)