emonTx4 & Pi pico

I’ve been doing a little EmonTx v4 & Pi Pico testing to explore what’s possible following @borpin’s recommendation. I’ve been able to get a basic serial to emoncms bridge working so far that meets the core requirement of sending the EmonTx data to emoncms but with a hardcoded SSID and WiFi password of course.

I’ve got an example working with both micropython and the arduino pi pico core. Code examples included below for anyone interested in this.

I think a small adapter pcb could work well for making this a connectivity option on the emonTx v4.

MicroPython


import network
import socket
from time import sleep
import machine
from machine import UART, Pin

import urequests
import uselect
import sys

ssid = 'SSID'
password = 'PASSKEY'

def connect():
    #Connect to WLAN
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect(ssid, password)
    while wlan.isconnected() == False:
        print('Waiting for connection...')
        sleep(1)
    ip = wlan.ifconfig()[0]
    print(f'Connected on {ip}')
    
try:
    connect()
except Exception as e:
    machine.reset()

buffered_input = []

uart0 = UART(0) # defaults 115200 baud

while(True):
    
    while uart0.any() > 0:
        c = chr(uart0.read(1)[0])
        buffered_input.append(c)

    if '\n' in buffered_input:
        line_ending_index = buffered_input.index('\n')
        data = "".join(buffered_input[:line_ending_index]).strip()
        buffered_input = []
        
        if data[0:3]=="MSG":
            req = "https://emoncms.org/input/post?apikey=apikey&node=emontx4pico&data="+data
            print(req)
            r = urequests.get(req)
            print(r.content)
            
    sleep(0.1)

Arduino Pi Pico core

#include <WiFi.h>
#include <HTTPClient.h>

// Replace with your network credentials
const char* ssid = "SSID";
const char* password = "PASSKEY";

String serverName = "https://emoncms.org/input/post";

String line = "";
String data = "";
String sub = "";
int data_ready = 0;

void setup() {

  // Start the Serial Monitor
  Serial.begin(115200);

  Serial1.begin(115200);

  // Operate in WiFi Station mode
  WiFi.mode(WIFI_STA);

  // Start WiFi with supplied parameters
  WiFi.begin(ssid, password);

  // Print periods on monitor while establishing connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    delay(500);
  }

  // Connection established
  Serial.println("");
  Serial.print("Pico W is connected to WiFi network ");
  Serial.println(WiFi.SSID());

  // Print IP Address
  Serial.print("Assigned IP Address: ");
  Serial.println(WiFi.localIP());

}

void loop() {

  while (Serial1.available()) {
  
    char c = char(Serial1.read());
  
    if (c=='\n') {
        data = line;
        data.trim();
        line = "";
        
        sub = data.substring(0, 3);
        if (sub=="MSG") {
            Serial.println(data);
            data_ready = 1;
        }
    } else {
        line = line + c; 
    }
  }

  //Send an HTTP POST request every 10 minutes
  if (data_ready) {
    data_ready = 0;
    //Check WiFi connection status
    if(WiFi.status()== WL_CONNECTED){
      HTTPClient http;

      String serverPath = serverName + "?node=pico2&data="+data+"&apikey=APIKEY";
      Serial.println(serverPath);
      
      // Your Domain name with URL path or IP address with path
      http.begin(serverPath.c_str());
      
      // Send HTTP GET request
      int httpResponseCode = http.GET();
      
      if (httpResponseCode>0) {
        Serial.print("HTTP Response code: ");
        Serial.println(httpResponseCode);
        String payload = http.getString();
        Serial.println(payload);
      }
      else {
        Serial.print("Error code: ");
        Serial.println(httpResponseCode);
      }
      // Free resources
      http.end();
    }
    else {
      Serial.println("WiFi Disconnected");
    }
  }
}
1 Like

The adapter PCB arrived, I havent spent a lot of time on adding silk screen text etc on this version yet but it’s working as a quick functional test.

On the right hand side there is the option to connect the RFM69cw radio to the Pico SPI and the DS18B20 temperature sensor input to a Pico digital input. These could allow the Pico to take over control of these components potentially allowing the EmonTx to be used as a RFM radio base-station as well as allowing for the reading of the DS18B20 addresses - I havent tested or written any code for those functions yet. I have only tested the serial interface so far.

2 Likes

Apparently, there is now a PiPicoW (with Wi-Fi)

Thanks @borpin, yes the wifi version is the variant Im using above, seems to work well!

1 Like

I can see this ending up as the default configuration IMHO.

Just a thought - will the six CT extender board fit under the pico adapter? If not, perhaps the pico could be rotated through 90 degrees as in the Pi zero adapter …

Good point, I am a bit constrained in it’s orientation by my choice of header location for the uart and spi, so it may be an either/or for the first batch at least. What I thought was a good approach for mechanical rigidity isn’t the best for mounting the pi pico or pi zero. I am actually planning on changing the header locations and layout on the next version to fix this.

1 Like

Thanks for the update. To be fair, a crystal ball would be useful, as I think the Pico W was only launched at the end of June this year!

1 Like

thumbsup beer_cheer

2 Likes