AT module and RN2483: not working with my Linux box

Posted on
Page
of 3
/ 3
Last Next
  • Hello,
    I am working on a project using a Rn2483. I think the AT module very valuable in this context and I tried to use it. But I experienced huge difficulties to make it working with Rn2483. Sending commands with \r\n at the end, such as ‘sys factoryYRESET\r\n’ are not executed by the radio module. I believe that's a cr/lf problem but I don't manage to master it. I looked at the code of the AT module checking that write statement is used instead of print. The code seems ok, so far I understand it....
    I wonder if the fact that my host machine is a Linux box may modify the way the code is minified specially the way Cr/lf is managed. This question comes from a remark in the AT module code: ‘’TODO: something odd about Espruino on linux seems to mean that extra '\n' get inserted */’’. This remarks rings the bell’, but I don't know what is hidden behind it.

    Can you please advice on this issue?
    Is there anybody who uses RN2483 + AT module?

    Thanks a lot.
    GeekBot

    PS:
    Epruino Pico is used on this project.
    Not tested on Windows yet.

  • Are you running Espruino itself on Linux, or are you running it on your Espruino Pico board?

    The remark was to do with what happens if you run the Espruino interpreter itself on Linux (eg. Raspberry Pi) - I think in that case it's more to do with Espruino's serial port implementation on Linux. Since you're only using Linux as the machine that talks to the Pico you should be fine (I use Linux for everything and don't have problems).

    Can you try at.debug() first? That should give you some debugging information about what's being sent/received.

    Also, have you checked that the baud rate/bits/parity is all correct?

  • Hello Gordon,

    Thanks for your answer.
    My code runs on Pico, not on Linux, (now I understand the comment in the code).
    Baud rate, parity and flow are correct.
    I am sure that the RN module works, because I tested it using the Foca adaptor and the GtkTerm with the same Serial parameters as those present in the code. It's the same problem on Serial1 and Serial2.

    My test code runing on Pico is this one:

    var SERIAL_OPTIONS = {
        "rx":B7,
        "tx": B6,
        "bytesize": 8,
        "parity": null,
        "stopbits": 1,
        "flow": null
    };
      
    Serial1.setup(57600, SERIAL_OPTIONS);
    
    var at = require("AT").connect(Serial1);
    
    at.debug();
    
    at.cmd("sys reset\r\n", 2000, function cb(d) {
      
      console.log(d);
      
    });
    
    

    When I run it, I get :

    echo(0);
    ["sys reset\r\n"
    =undefined
    undefined

    I should get the reset return message which gives RN2483 version, date...
    The RN module is correctly connected and voltage levels are correct on the PINs. I use a breakboard from Dr Azzy.

    So my question is: Is the code above correct ? Should it work ?
    Thanks a lot.
    GeekBot

    Just to clarify how to send commands from a Linux GtkTerm to the RN2483 (using Foca adpator):
    1/ Uncheck the CRLF option in Gtkterm
    2/ You need to add CTRL-M CTRL-J manually to the command (to send the CR LF), then the command get executed correctly on the RN2483.

  • Yes, what you've got there should work. How about totally stripping it back to basics and seeing if anything happens:

    var SERIAL_OPTIONS = {
        "rx":B7,
        "tx": B6,
        "bytesize": 8,
        "parity": null,
        "stopbits": 1,
        "flow": null
    };
      
    Serial1.setup(57600, SERIAL_OPTIONS);
    Serial1.on('data', function(d) {
      console.log(">>"+JSON.stringify(d));
    });
    Serial1.write("sys reset\r\n");
    

    If that doesn't work then perhaps your wiring is wrong? TX should go to RX and vice versa (and obviously you need GND too).

    If it does work, perhaps the module itself doesn't send newlines in the way that the AT library is expecting? In that case it might be that the library isn't detecting a newline, so isn't calling the callback with the data.

  • Thank you Gordon,
    We are sure that there is ground problem or tx/rx confusion. I work with another person and we double check the wiring. We receive the reset message from the module at power on, so it means that at least basic serial parameters look OK.
    The snippet you provide above produces nothing back. It seems that the RN module doesn't catch the \r\n. Looking on the line with the Foca converter tx input, we see the string with CR/LF is emitted by Espruino. So it seems clear that the module doesn't interpret the command. What is strange is that the same command issued by the Foca adpator is executed by the module. So the Foca adaptor and Espruino don't behave exactly the same, and can't manage to undestand where they are different.
    One way if to check the electrical signals on the line to see if we are exactly at the good speed or if the Espruino or module clocks and serial speed are shifted. But I need a memory oscilloscope for that, and I don't have yet...
    Any idea is welcome, we are totally stuck on this issue.
    Best regards
    GeekBot

  • Thanks for using my breakouts :)

    Two things I've done:

    With digital 'scope, you can crank the scan speed WAY down and try to see if you can catch what it's doing.

    Run serial lines to the RX of another adapter to listen to what's being sent. I have a contraption that uses a few '339's, and outputs the TX/RX lines each going into the Rx line of another connected serial adapter, and the Tx lines of those adapters let me inject text into each of the lines I'm probing (though this needs to be used with caution, because the 339 could be fighting an output).

  • Thank you Dr Azzy, I did your recommendation and found out that it was not a clock problem. Then I focussed on the init procedure of the module and found out that the problem was tricky, due to an involuntary break condition during module power up which puts the module in a locked state. So, I reworked the init procedure carefully to avoid this break condition and now the module works perfect. I also confirm that your breakout is a great device.
    GeekBot

  • Could you post up a bit more information about what caused the problem for you/how you fixed it?

    I think others would be interested in this module (in fact I received some for a project just last week) so it'd be a huge help if we share some information on it - in fact it'd be great if you were able to share your code so we could turn it into a module.

  • FYI, I worked on the RN2483 this week-end, and I finally was able to send some datas on the server. here is the debug script I used, in case you need it:

    var rxbuf=[];
    var initState=0;
    var devAddr="YOUR_DEV_ADDR";
    var nwkSKey="YOUR_NETWORK_SESSION_KEY";
    var appSKey="YOUR_APPLICATION_SESSION_KEY";
    Serial1.setup(57600, { tx:B6, rx:B7 });
    Serial1.on('data', function (data){
      if(data.indexOf('\n')>-1)
      {
        console.log(rxbuf);
        if(rxbuf.indexOf("mac_tx_ok")>-1)
          digitalWrite(LED2,1);
        else
          digitalWrite(LED2,0);
        rxbuf=[];
      }
      else
        rxbuf+=data;
    });
    
    function loraReset(){Serial1.print("sys reset\r\n");}
    function loraGetVer(){Serial1.print("sys get ver\r\n");}
    function loraGetVcc(){Serial1.print("sys get vdd\r\n");}
    function loraGetHWEUI(){Serial1.print("sys get hweui\r\n");}
    function loraSetDevAddr(addr){Serial1.print("mac set devaddr "+addr+"\r\n");}
    function loraSetNwkSKey(key){Serial1.print("mac set nwkskey "+key+"\r\n");}
    function loraSetAppSKey(key){Serial1.print("mac set appskey "+key+"\r\n");}
    function loraSetADR(state){
      var OnOff=( (state=="ON") || (state=="on") || (state=="On") )?"on":"off"; 
      Serial1.print("mac set adr "+OnOff+"\r\n");}
    function loraGetDR(){Serial1.print("mac get dr\r\n");}
    function loraGetChannel(){Serial1.print("mac get ch\r\n");}
    function loraGetBand(){Serial1.print("mac get band\r\n");}
    function loraGetRxDelay2(){Serial1.print("mac get rxdelay2\r\n");}
    function loraGetpwridx(){Serial1.print("mac get pwridx\r\n");}
    function loraJoinABP(){Serial1.print("mac join ABP\r\n");}
    function loraGetStatus(){Serial1.print("mac get status\r\n");}
    function convertToHex(str) {
        var hex = '';
        for(var i=0;i<str.length;i++) {
            hex += ''+str.charCodeAt(i).toString(16);
        }
        return hex;
    }
    
    function loraTRX(data){
      digitalWrite(LED2,0);
      console.log("Sending: "+data);
      Serial1.print("mac tx uncnf 1 "+convertToHex(data)+"\r\n");
      //setTimeout(loraGetStatus,150);
    }
    
    function init()
    {
      switch(initState)
      {
        case 0:
          console.log("LoRa init begin...");
          console.log("resetting...");
          loraReset();
          initState++;
          break;
        case 1:
          //console.log("\nVersion:");
          //loraGetVer();
          initState++;
          break;
        case 2:
          //console.log("\nVCC:");
          //loraGetVcc();
          initState++;
          break;
        case 3:
          console.log("\nHW EUI:");
          loraGetHWEUI();
          initState++;
          break;
        case 4:
          console.log("\nSetting devAddr");
          loraSetDevAddr(devAddr);
          initState++;
          break;
        case 5:
          console.log("\nSetting nwkSKey");
          loraSetNwkSKey(nwkSKey);
          initState++;
          break;
        case 6:
          console.log("\nSetting appSKey");
          loraSetAppSKey(appSKey);
          initState++;
          break;
        case 7:
          console.log("\nDisabling Adaptative Data Rate");
          loraSetADR("off");
          initState++;
          break;
        case 8:
          //console.log("\nRetrieving data rate...");
          //loraGetDR();
          initState++;
          break;
        case 9:
          //console.log("\nRetrieving channel...");
          //loraGetChannel();
          initState++;
          break;
        case 10:
          //console.log("\nRetrieving band...");
          //loraGetBand();
          initState++;
          break;
        case 11:
          //console.log("\nRetrieving rxDelay2...");
          //loraGetRxDelay2();
          initState++;
          break;
        case 12:
          //console.log("\nRetrieving power output index value...");
          //loraGetpwridx();
          initState++;
          break;
        case 13:
          console.log("\nJoining ABP...");
          loraJoinABP();
          initState++;
          break;
        case 13:
          console.log("\nStatus: ");
          loraGetStatus();
          initState++;
          break;
        case 14: 
          initState=-1;
          break;
        default:break;
      }
      if(initState!=-1)
        setTimeout(init,50);
    }
    
    function BTNHandle()
    {
     var a=getTime().toString().slice(7,9); 
      loraTRX(a);
    }
    
    setTimeout(init,1000);
    setWatch(BTNHandle,BTN,{repeat:true,edge­:'falling',debounce:50});
    save();
    
  • Great - thanks! What did you use as the server out of interest?

  • I tried using The Things Network infrastructure as it becomes popular in Switzerland (thx @gnz for your efforts)

  • The problem I had is relative to power up and reset of both Espruino and RN2483. When the Espruino boots, rx and tx lines are set as GPIO and tired down to 0. The RN2483 sees this as a break condition and waits indefinitely for the 0x55 character. You can't escape this state. The only way is to make a hard reset on the module while tx (of Espruino) is set to 1. So the right sequence is:
    1/ Power up the system (Espruino and RN2483)
    2/ Set Serial configuration (this make the Serial GPIO tx @ 1)
    3/ Wait a few hundreds of ms
    4/ Do a hard reset of the RN module using one Espruino GPIO line (keeping tx espruino at 1)
    5/ Wait 400 ms or catch RN reset message
    6/ Go ahead, the system is ready.
    HTH
    GeekBot

  • Huh - so if the problem is the RN2483 seeing a low on it's RX line at start up, a 10k pullup to 3.3v on the RX line might help - the pins should get initialized as high impedance, so a pullup should ensure that they don't start out low...

  • @DrAzzy, I discovered the problem looking at signals with my oscilloscope, I am quite sure that my code didn't pull down the line before, but a mistake on my side is always possible... I confess that I am a bug maker... However, if GPIOs are in high impedance state at reset, the oscilloscope can pull the line down by itself since it has a 1 M input impedance only. Anyway, the module was stuck in the break condition. I like the idea of putting a pullup, I will test it. However, when power goes on, I always fear a glitch on the GPIO that could leave the module in the deadlock. Do you think that when power goes up, that GPIO will remain in high impedance? No glitch? I have to look at the ST datasheet...

  • Great - thanks for the explanation! I probably would have hit that as well :)

  • Do you think that when power goes up, that GPIO will remain in high impedance? No glitch?

    Unfortunately you cannot be sure there won't be any glitch at power-up because of the high impedance. As @DrAzzy said, only a pullup will give you the guarantee that the TX line of your STM32 is at a known state at power-up.
    Another way to avoid any confusion may be to hard reset the RN2483 after having configured the USART interface (pin 32 of RN2483), but then you need an extra wire...

  • Yes, Jean-Philippe, I had to drive the RST line of the module with an extra wire.
    GeekBot

  • @Jean-Philippe_Rey Thanks for the code! I just tried it and it works like a charm! I had a half-written implementation of something similar, but I was having problems with the module itself and never got around at giving it another spin until now.

    It would be neat if we can polish your code and align it to the other official TheThingsNetwork libraries (such as this one that targets Arduino+RN2483). If you put that in some github repo, I'd love to contribute to it.

    Cheers

  • Just to add, IMO it'd be even better if it could be an Espruino module so you could just require("RN2483") :)

  • @Gordon totally agree, but isn't that just a final "publishing" step once the module is done?

  • @gnz It works because it is 99% based on your code ;-)

    I totally agree with both of you that it could be a great opportunity for the emerging TTN community to have access to a real module.

    Unfortunately I am not comfortable enough with JS to create a module by myself. Instead, I would love to contribute and fill the gaps if anyone could create the module skeleton.

  • @gnz, yes true. Although from the point of view of tracking changes you could just stick it in your own branch of EspruinoDocs and then merge in when ready.

    I have one here, so I'll take a quick look at making a simple module this morning - but it'd be great if others could contribute once I've stuck the basics up.

  • @Gordon cool...! if you start, I'll tag along and add stuff to it.

  • Ok, there's now a module. It's not published yet, but is on GitHub.

    Since it's not on the website yet, you can use it by URL:

    var RN2483 = require("http://raw.githubusercontent.co­m/espruino/EspruinoDocs/master/devices/R­N2483.js");
    Serial1.setup(57600, { tx:B6, rx:B7 });
    var lora = new RN2483(Serial1, {reset:B3, debug:true});
    
    lora.radioTX("Hello World!", function() {
      console.log("Data sent");
    });
    

    If you want to add extra stuff, it's easy - just do:

    RN2483.prototype.setTXPower = function(pwr, callback) {
      this.at.cmd("radio set pwr "+pwr+"\r\n",1000,callback);
    };
    

    Right now I don't have a Things Network gateway within range, so I've done what I can test - which is radio->radio comms without using LoRaWAN. Hopefully this is a good start though.

    I've used the AT command library to make this kind of thing a lot easier - everything has timeouts.

    I have used promises for getStatus. This is a really tidy way of chaining stuff like the initialisation code that was posted above.

    The only problem is it's relatively new - you'll need an up to date build of Espruino (eg. one newer than 1v87) for it to work I'm afraid. I think it's worth it though, and at some point I'll be swapping existing libraries like the ESP8266/GSM ones to use it too.

    Any questions just ask - it'd be great to get a nice easy to use library that works with The Things Network. Even better if someone could come up with some instructions for setting up your own LoRaWAN :)

  • Awesome work!
    Using the AT library +Promises is the way to go even if it is relatively new.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

AT module and RN2483: not working with my Linux box

Posted by Avatar for GeekBot @GeekBot

Actions