Moddable-OpenSource / moddable

Tools for developers to create truly open IoT products using standard JavaScript on low cost microcontrollers.
http://www.moddable.com
1.29k stars 235 forks source link

Connecting Moddable 2 to the internet using GSM #231

Closed Adarkazanli96 closed 4 years ago

Adarkazanli96 commented 4 years ago

Hello, I recently purchased an Adafruit FONA board from amazon: https://www.amazon.com/Evalution-Adafruit-Cellular-Breakout-Version/dp/B00N429XBI

I'm currently trying to get my Moddable application to connect to the internet without wifi, but there's no documentation on how that might be possible (which I understand since it's probably not a common use of the moddable.) I understand that from the description of the Adafruit device, I would need to connect the device to a microcontroller with a UART, where it can send and receive commands over the RX/TX pins.

IMG_3224

I see the RX and TX pins on the moddable two, on the side where you would normally attach the programmer. However, since the hardware documentation is limited, I was wondering if the experts at Moddable can tell me which pins I would use on the moddable two as well explain how to program the moddable to use go through the gsm instead of the wifi when it sends http requests. Please get back to me, thanks!

mkellner commented 4 years ago

Hello! In the contributed/serial directory is an implementation of a serial module that works with the esp32.

The document in that directory will show you what to change in the manifest.json file to set the pins that you'd like to use. See the Configuration section.

I have used the serial module to connect to a SIM7100 module for GPS and SMS. I'll upload that code in future OpenSource drop.

However, I have not connected it as a network endpoint. I imagine you will need to write some native code to interact with the esp32 libraries to connect via serial. Once the network is connected, I don't see why the rest of the network stack wouldn't work.

mkellner commented 4 years ago

There is now a directory contributed/serial/drivers/sim7100 that shows some examples of using SMS and GPS from the SIM7100 module.

Adarkazanli96 commented 4 years ago

There is now a directory contributed/serial/drivers/sim7100 that shows some examples of using SMS and GPS from the SIM7100 module.

Great! I'm working with the SIM800H module, and I was just wondering if the same could would work for it. It should right? I might need to reconfigure the pins, but other than that I don't see why it should be different. Please correct me if I'm wrong, I'm still new to this haha.

mkellner commented 4 years ago

The technique used for the SIM7100 module should work with the SIM800H. The specific AT_*** commands may be different between modules so get the command reference for your module. You'll still be able to debug as you will be using a different serial port than the one used for xsbug. Xsbug uses the RX/TX which connects to the programmer.

Adarkazanli96 commented 4 years ago

The technique used for the SIM7100 module should work with the SIM800H. The specific AT_*** commands may be different between modules so get the command reference for your module. You'll still be able to debug as you will be using a different serial port than the one used for xsbug. Xsbug uses the RX/TX which connects to the programmer.

Hi, sorry for all the questions. I’m still alittle stuck, but I really appreciate how much help this thread has been so far!

Using your guidelines, I managed to get my SIM800H module to connect to the internet using the AT commands in the SIM800 documentation found here https://www.elecrow.com/wiki/images/2/20/SIM800_Series_AT_Command_Manual_V1.09.pdf

For this, I used the commands: this.serial.write(AT+SAPBR=3,1,"Contype","GPRS"\r) //set the connection type this.serial.write(AT+SAPBR=3,1,"APN","epc.tmobile.com"\r); //configure APN this.serial.write(AT+SAPBR=1,1\r) //allocate IP address, thus establishing GPRS connection

And then I used the command this.serial.write(AT+SAPBR=2,1\r) to read the IP address from the response

Since the sim module was assigned an IP address, I assume the module is connected to the internet through T-mobile network.

Now if I use the moddable two’s Net library to retrieve the moddable two’s IP address, I get an empty string. I assume this means that the moddable is not connecting to the sim module at a serial level. Which I don’t understand considering I configured the serial port in the manifest file shown in the screenshot below.

Screen Shot 2019-07-24 at 4 09 20 PM

I must be missing something, but I can't quite figure it out. I'm still very new to this

mkellner commented 4 years ago

I think that you're about as far as you can get at this point. You've connected to the module, issued commands and received data. The module has an IP address and endpoint to the Internet, but there is nothing in the esp32 networking code that is connected to the serial port, yet. Once the module connection is established, you'd connect it to esp32's LWIP.

The next part of this project would be to establish that connection. At that point, the esp32 network code (LWIP) will be aware of the IP address and the Moddable code (which uses LWIP) should work.

I note that there is not an example in the Moddable SDK demonstrating this.

This project looks like it is doing something similar to what you want to do: https://github.com/loboris/ESP32-PPPOS-EXAMPLE.

To pursue this path, look at the code that does the following: (from the github site)

  1. Creates the pppos client task which initializes modem on UART port and handles lwip interaction

which basically calls int ppposInit() from this pppos component

You would need to make a new module that incorporates native ESP32 code (the pppos component above). You could follow the esp32 conventions and add it as a ESP32 IDF component, or maybe just grab the two pppos files and replace the CONFIG_GSM_xxx defines with constants or some new MODDEF_xxx defines that you could add to the manifest.json file. I'd suggest the latter as it reduces the amount of build-system change and the code appears to be unencumbered. ie: This example code is in the Public Domain (or CC0 licensed, at your option.)

The JavaScript interface would probably look very roughly like the WiFi class. That is, the constructor would have the phone number and APN (or whatever connection parameters are necessary) and establish the connection.

This is quite a bit to digest. Let me know if you have questions or need more guidance.

Adarkazanli96 commented 4 years ago

@mkellner If I understand you correctly, you’re recommending that I make a module that incorporates the c code for defining int ppposInit() (aka libGSM.c) and turning it into something that resembles the WiFi class? And you’re implying this module would essentially be a JAVASCRIPT file, since in the end it will adopt a javascript interface similar to the WiFi class? Or would it really be a c file since it will be calling ppposInit(). Because you also mentioned that I should reference the code that creates the ppos client task and initializes modem on UART port found in the same repo here: https://github.com/loboris/ESP32-PPPOS-EXAMPLE/tree/master/main

I went ahead with the assumption of using the pppos_client_main.c file as the module.

First, I grabbed libGMS.c (pppos component) and pppos_client_main.c (soon to be module) and put them in a local folder within my application like this:

Screen Shot 2019-07-25 at 6 18 00 PM

I then defined the constants mentioned in the pppos component file:

define UART_GPIO_TX 17

define UART_GPIO_RX 16

define UART_BDRATE 115200

define CONFIG_GSM_APN "epc.tmobile.com"

const char PPP_User = "username"; const char PPP_Pass = "password";

Lastly, I included what I thought to be the module to the manifest.json file:

Screen Shot 2019-07-25 at 6 15 41 PM

I got a ton of errors and spent the day trying to resolve them. I even tried deleting code that might be deemed unnecessary. Still no luck :(

I’m more than likely doing something wrong, either with the file structures, or with the way I went about creating the module.

mkellner commented 4 years ago

I don't think you need anything from the pppos_client_main.c file except the init call ppposInit(). That would be called from the constructor of the sim800 object.

Directory structure, I'm thinking something like this to start with.

manifest.json
main.js
sim800/
    sim800.js
    sim800.c
    libGSM.c
    libGSM.h

The module is really simple (to get started). Assumes all the connection parameters are hard coded in the C code to simplify explanation. Since the libGSM code is in C, we need a way to call it from JavaScript.

XS provides the @ language syntax extension to implement JavaScript functions in C.

sim800.js:

class SIM800 @ "xs_sim800_destructor" {
     constructor(dictionary) @ "xs_sim800_constructor";
}

In the C code, the constructor just calls the ppposInit routine from the libGSM code.

sim800.c:

void xs_sim800_constructor(xsMachine *the) {
    if (ppposInit() == 0)
            xsUnknownError("can't connect");
}

void xs_sim800_destructor(void *data) {
    // close the connection, free up memory and resources
}

In your app, you'd import the module and instantiate the class. This will call its constructor which will make the network connection.

main.js:

import SIM800 from "sim800";

let myConnection = new SIM800();
// if ppp connected then we should be able to do networky stuff here

The manifest would have something like this:

    "modules": {
        "*": [
            "./sim800/*",
            "./main",
        ],
    },

I don't think you need the serial module at all anymore, as the ppposInit() call connects to the UART.

Adarkazanli96 commented 4 years ago

It works!!! I’m able to run the websocket client application without using wifi.

Screen Shot 2019-07-27 at 10 11 52 AM

Something I forgot to mention earlier was that I kept receiving a ppp_pcb type undefined error when libGSM.c was being compiled. The issue appeared to have been resolved when I enabled CONFIG_PPP_SUPPORT in sdkconfig.defaults.

I also finally knew what you meant when you mentioned the language syntax extension. See I figured that ppposInit() must be called through a javascript interface. However, I did not know how it would be possible considering it was written in c. This is why I tried using that other c file to call ppposInit(). but that route just lead me to a bunch of errors.

Thanks alot @mkellner for your help. I learned a lot from this experience, as well as realized the powerful capabilities of some of these devices

phoddie commented 4 years ago

Very cool. Congratulations! I would be great to have an example with documentation so other developers can use this too.

diogoviannaaraujo commented 4 years ago

Hi, im trying to connect a sim868 using pppos, been basing my code in esp-idf`s pppos client example, since that one that was shared above was for idf v2.2. Im getting the connected message but im not getting IP using Net module, is that expected? @Adarkazanli96 what idf version was you using? can you share a example code? Im thinking of creating a moddable-pppos repository with the module in the next days.

Adarkazanli96 commented 4 years ago

Attached to this message you'll find all the code I believe I used, but I can't be sure exactly since I hadn't been working on the moddable since I posted this (and I also wouldn't know how to answer your question). Good luck!! Archive.zip

diogoviannaaraujo commented 4 years ago

Ive been able to connect using pppos with esp-idf example code and using it to connect to MQTT over SSL sockets.

But since I lack skills in C and XS my implementation is getting kind of unstable especially in the reconnection part. It starts blocking the main thread, part because I can't deactivate it correctly part because I don't get xtask and all that stuff.

Ive been studying MicroPython network.PPP implementation and I think its a great base, leave modem start chat out of the module and just implements a way to pass a read/write stream to lwip.

Other problem is the lack of oficial Serial module implementation by moddable, the contributed module blocks while reading, and trying to build something on top of non officially supported Serial module is not motivating.

But I may give a try next days. with nbiot and lte-m cellular connection is getting so 'normal', it would be nice if moddable had a nice support for it out of the box, as it has with wifi