Mongoose OS Starter Kit quick Start Guide for Google IoT Core

Mongoose OS IoT Starter Kit is recommended by Google IoT Core portal and provides you with a quick way to start IoT development on microcontrollers.
This quick start guide and reference materials include the following:

Components:

 Mongoose OS

 ESP32 Feather

 Google IoT Core

  1. Mount the HUZZAH32 board to the breadboard
  2. Connect HUZZAH32 to your computer with a micro-USB cable
  3. Follow installation instructions to install mos tool on your computer
  4. Start mos tool. A Web UI will appear, with the connection dialog
  5. Select "Serial Port" click Connect
  6. Choose "iot-kit-esp32-latest" firmware, click Flash.
  7. Enter your WiFi credentials, click "Save"
  8. Click on "START PROTOTYPING". That should open the init.js file on your device
  9. Follow the cloud side setup instructions to register your device on Google IoT Core
  10. Login to Google IoT Core Console. Make sure you have your device registry created, and you have your device listed on it.
Troubleshooting: post on Mongoose OS forum or talk on Mongoose OS chat.

In this tutorial, we'll use the DHT22 temperature/humidity sensor and send measurements to the Google IoT Core.

  1. Mount DHT22 sensor to the breadboard:
    • Use the black jumper wire to connect GND pin to the HUZZAH32 GND pin
    • Use the yellow jumper wire to connect Data pin to the HUZZAH32 GPIO pin 21
    • Use the red jumper wire to connect VCC pin to the HUZZAH32 VCC pin
  2. In the mos Web UI, open the init.js file
  3. Copy/paste the following code:
    load('api_config.js');
    load('api_dht.js');
    load('api_mqtt.js');
    load('api_timer.js');
    
    let topic = '/devices/' + Cfg.get('device.id') + '/events';
    let dht = DHT.create(21, DHT.DHT22);
    
    Timer.set(5000, true, function() {
      let msg = JSON.stringify({ t: dht.getTemp(), h: dht.getHumidity() });
      let ok = MQTT.pub(topic, msg, 1);
      print(ok, msg);
    }, null);
  4. Click the "Save and Reboot" button
  5. Verify that data is sent to the PubSub. Run console command:
    gcloud beta pubsub subscriptions pull --auto-ack iot-subscription --max-messages=999
    +---------------+------------+-----------------+-----------------------+
    |            DATA            |    MESSAGE_ID   |       ATTRIBUTES      |
    +----------------------------+-----------------+-----------------------+
    | {"h":42.599998,"t":24.23}  | 144935373963880 | deviceId=dev1 dev.... |
    | {"h":42.599998,"t":24.22}  | 144937730266979 | deviceId=dev1 dev.... |
    ...

In this tutorial, we'll send a message to Google IoT Core on a button press.

  1. Mount the push button on the breadboard:
    • Use the yellow jumper wire to connect the HUZZAH32 GPIO pin 21 to the first button connector
    • Use the red jumper wire to connect the 3.3v pin to the second button connector
  2. In the mos Web UI, open theinit.js file
  3. Copy/paste the following code:
    load('api_config.js');
    load('api_gpio.js');
    load('api_timer.js');
    load('api_mqtt.js');
    
    let topic = '/devices/' + Cfg.get('device.id') + '/events';
    let pin = 21;
    
    GPIO.set_mode(pin, GPIO.MODE_INPUT);
    GPIO.set_pull(pin, GPIO.PULL_DOWN);
    GPIO.set_button_handler(pin, GPIO.PULL_DOWN, GPIO.INT_EDGE_NEG, 200, function() {
      let msg = JSON.stringify({ time: Timer.now() });
      let ok = MQTT.pub(topic, msg, 1);
      print(ok, msg);
    }, null);
  4. Click the "Save and Reboot" button
  5. Press on a push button to trigger sending of the message
  6. You can subscribe to the sub1 PubSub subscription programmatically, catch those messages and perform any custom action

In this tutorial, we'll demonstrate how to control the device remotely by sending commands from the cloud to switch an LED on/off.

  1. Connect an LED by plugging it to the pin 21 and GND.
  2. Open init.js, paste this code, click "Save + Reboot":
    load('api_config.js');
    load('api_gpio.js');
    load('api_timer.js');
    load('api_mqtt.js');
    
    let topic = '/devices/' + Cfg.get('device.id') + '/config';
    let pin = 21;
    
    GPIO.set_mode(pin, GPIO.MODE_OUTPUT);
    
    MQTT.sub(topic, function(conn, top, msg) {
      print('Got config update:', msg.slice(0, 100));
      let obj = JSON.parse(msg);
      if (obj) GPIO.write(pin, obj.on);
    }, null);
  3. Start terminal, send commands to the cloud to turn the device on:
    gcloud beta iot devices configs update --device $DEVICE_ID \
      --project $PROJECT_ID --region europe-west1 --registry registry1 \
      --config-data '{"on": true}'
  4. And to turn the device off:
    gcloud beta iot devices configs update --device $DEVICE_ID \
      --project $PROJECT_ID --region europe-west1 --registry registry1 \
      --config-data '{"on": false}'
  5. Read more Google IoT Core docs on cloud-to-device configuration

In this tutorial, we'll use a door sensor to generate messages and send them to Google IoT Core.

  1. Connect door sensor by plugging it to the pin 21 and GND.
  2. Open init.js, paste this code, click "Save + Reboot":
    load('api_config.js');
    load('api_gpio.js');
    load('api_mqtt.js');
    
    let pin = 21, state = 0;
    let topic = '/devices/' + Cfg.get('device.id') + '/events';
    
    GPIO.set_button_handler(pin, GPIO.PULL_UP, GPIO.INT_EDGE_POS, 200, function() {
      let value = GPIO.read(pin);
      let msg = JSON.stringify({ state: value ? 'open' : 'closed' });
      if (value !== state) {
        state = value;
        let ok = MQTT.pub(topic, msg, 1, true);
        print(ok, topic, msg);
      }
    }, null);
  3. Move the other part of the door sensor to trigger messages:
    [Aug 21 16:08:29.942] 1 /devices/esp32_0C1E40/events {"state":"open"} 
    [Aug 21 16:08:40.971] 1 /devices/esp32_0C1E40/events {"state":"closed"} 
In this tutorial, we'll send messages to the cloud when a PIR sensor detects some motion.
1. Connect the PIR sensor to the breadboard: the black jumper wire to the GND pin, the red jumper wire to the 3.3v pin, and the yellow jumper wire to the GPIO pin 21.
2. Open init.js, paste this code, click "Save + Reboot":
load('api_config.js');
load('api_gpio.js');
load('api_mqtt.js');
load('api_timer.js');

let pin = 21;
let topic = '/devices/' + Cfg.get('device.id') + '/events';

GPIO.set_button_handler(pin, GPIO.PULL_DOWN, GPIO.INT_EDGE_ANY, 200, function() {
  let msg = JSON.stringify({ motion: GPIO.read(pin) });
  let ok = MQTT.pub(topic, msg, 1);
  print(ok, msg);
}, null);
3. Note when a motion sensor detects a motion, it sets the signal pin (in our case, GPIO 21) to the high voltage state (1), then keeps it high for some time, then drops to low voltage (0). We detect both events:
[Aug 25 13:35:38.364] 1 {"motion":0} 
[Aug 25 13:35:42.558] 1 {"motion":1}
In this tutorial, we'll drive the servo motor.
1. Connect the servo to the breadboard: the black jumper wire to the GND pin, the red jumer wire to the 3.3v pin, and the yellow jumpre wire to the GPIO pin 21.
2. Open init.js, paste this code, click "Save + Reboot":
load('api_pwm.js');
load('api_rpc.js');

RPC.addHandler('PWM', function(args) {
  print('Got RPC:', JSON.stringify(args));
  PWM.set(args.pin, args.freq, args.duty);
  return true;
});
3. This installs a Remote Procedure Call (RPC) handler which you can trigger.
4. Click on the "Device Services" tab, click on "PWM" service you just created, enter { "pin": 21, "freq": 50, "duty": 7 } and click on the "Call RPC service" button:
[Aug 25 15:22:27.967] Got RPC: {"duty":7,"freq":50,"pin":21}
5. Experiment with different values of duty e.g. from 2 to 15, to rotate the servo at different angles