How would you send data from an Nano 33 IoT to a computer?

Hi guys, this is my first post on this forum :slight_smile:

I would like / am trying to send data from a wireless Arduino Nano 33 IoT to a computer. I will be using this data in another application TouchDesigner; which supports WebSockets, WebServers and WebClients similar to Processing Libraries.

I tried to send data from the 33 IoT to my computer following some example files from WifiNINA and ArduinoHttpCient (example. SimpleWebSocket ) Libraries. I also followed David Cuartielles video tutorial, who sends a message from an MKR1010 to Processing on the computer but still didn't manage.

Can you direct me to how is this achievable? Would it be easier to have another 33 IoT that receives the data from the other board which is sending the wireless data, and then parse it with the serial? Or is there a better way?

Would love to hear your thoughts on this.

Thanks in advance :heart:

your Arduino Nano 33 IoT has Wi-Fi, Bluetooth and BLE capabilities.

You need to decide what transport layer you want to pick and write code to support that.
Since your recipient app supports a web protocol, I'd say Wi-Fi + a WebClient seems the path of least resistance.

1 Like

If your application can communicate using raw TCP/UDP sockets, it is much easier to implement. You don't have to deal with parsing HTML headers etc.

For testing raw TCP/UDP sockets, the Linux utility nc works very well. The following creates a server on your Linux PC listening on port 8080

root@srv:~# nc -k -l -N -v 8080

You can even "visit" the page by pointing your browser to it

http://ip_address:8080

ddd

1 Like

Hey @J-M-L @hzrnbgy thanks so much for your quick replies.

I was thinking that Wifi would be the best choice. It's the HOW that I am being stuck at mostly. Should the app on the computer run a WebClient and the Arduino Boards be programmed as WebServers?

I forgot to mention something important, I need the data in realtime at a rate of around 10 times per second. Would this be a problem with the above solution?

While continuing to search for ways to creating a communication between my Arduino board and computer, I found that OSC could be a simple and very good solution since it works with devices that are connected to same network. I will look into this.

@hzrnbgy OSC can use the UDP protocol, so I think I am heading to somewhere close to what you suggested :slight_smile:

The image above shows the parameters of the OSC_In node in TouchDesigner.

that sounds promising. UDP does not guarantee delivery so you'll have to think what it means for your application

Has the OP considered using MQTT ? Running the Broker on a local PC that the IoT devices can communicate with, quite extensible.

I use a RPi for my MQTT (and home bridge) server, way less power required for 24x7 operation.

I, also, have my MQTT Broker on a RPi.

:slight_smile: good

Is MQTT viable for the OP's 10Hz requirement do you think? Not disputing it, just don't know.

One of my ESP32's is sending/receiving data at 11 times a second. I can write that at 11 times a second the thing works and lasts a long time. 10 times a second, I've not tried it.

I was curious if that would work too

So I just tried with this code sending 1000 messages at 20Hz to my RPi on my local network (ESP32 connected through Wi-FI, RPi on the LAN via Ethernet at 10.0.0.23, MQTT server with no login/pwd).

#include <WiFi.h>
#include <PubSubClient.h>

const char* ssid = "***************";
const char* password = "***************";
const char* mqttTocic = "/something/to/test";
const size_t payloadSize = 20;
char mqttMessage[payloadSize];

IPAddress mqttServerIP(10, 0, 0, 23); // 10.0.0.23

WiFiClient wifiClient;
PubSubClient client(wifiClient);

void sendMqttMessage() {
  if (client.connected()) {
    if (client.connect("ESP32")) {
      snprintf(mqttMessage, payloadSize, "%lu", millis());
      client.publish(mqttTocic, mqttMessage, false); // false for not retained
    } else {
      Serial.print("MQTT Publish failed, rc=");
      Serial.println(client.state());
    }
  }
}


void setup() {
  Serial.begin(115200); Serial.println();
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("WiFi Failed!");
    while (true) yield();
  }
  Serial.println("WiFi OK!");

  client.setServer(mqttServerIP, 1883);
  if (!client.connected()) {
    if (!client.connect("ESP32")) {
      Serial.println("MQTT Server not reacheable!");
      while (true) yield();
    }
  }
  Serial.println("MQTT OK!");

  Serial.println("press a key to start!");
  while (Serial.read() == -1);
  Serial.println("Sending messages!");
}

void loop() {
  const unsigned long period = 50;
  static unsigned long count = 0;
  static unsigned long startTime = millis();
  static unsigned long lastTime = startTime;
  if (millis() - lastTime >= period) { // 10Hz
    sendMqttMessage();
    if (count++ >= 1000) {
      unsigned long deltaT = millis() - startTime;
      Serial.print("sent 1000 messages in ");
      Serial.print(deltaT);
      Serial.println(" ms");
      while (true) yield();
    }
    lastTime += period;
  }
}

on my RPi I ran the following command

mosquitto_sub -h localhost -t "/something/to/test"

Then once I typed enter in the Serial monitor (sending something like CR or CR/LF or LF) at 115200 bauds, I saw in the remote shell terminal the MQQT messages flowing in

22102
22152
22202
22252
22302
22352
22402
22452
22502
22552
22602
22652
22702
22752
22802
...
71952
72002
72052
72102

and the Arduino said:

WiFi OK!
MQTT OK!
press a key to start!
Sending messages!
sent 1000 messages in 50051 ms

I looked at the timing of the 1000 values in a spreadsheet, the millis values are all 50ms apart

so it seems you can handle 20Hz fine that way, it did not skip a beat.

if you want to test the code, you'll have to modify the Wi-Fi connexion info and the MQTT server IP address.

const char* ssid = "***************";
const char* password = "***************";
IPAddress mqttServerIP(10, 0, 0, 23); // 10.0.0.23

of course the notification of the MQTT server will possibly add some delay/latency

I would, also, suspect the QoS setting would have an impact on the transmission rate. You used QoS of 0?

Has the OP considered using MQTT ? Running the Broker on a local PC that the IoT devices can communicate with, quite extensible.

He did specify an application called TouchDesigner as the recipient of the messages. Can that work with MQTT?

The library can only publish QoS 0 messages, so yes.

Hey guys thanks again for the all your help and suggestions.

Sorry for not being specific in what I want to achieve. What I want is to connect two IMU sensors to the 33 IoT (or maybe even use the built-in one), that will be worn on a dancer/performer on each hand, and the performers will control music and visuals with their movement. The idea here is to connect both computer and Arduino boards to same WiFi network. Would this work with OSC over UDP?

@Idahowalker somebody else suggested me to work with MQTT, but thought it was an overkill for my application, but I might be wrong and could work better. I need to dig deeper on it.

In the meantime I have been trying to get some data with OSC using the UDP protocol. I have mixed and joined some examples from the WifiNINA and OSC libraries to connect to WPA Network, and to actually send the data wirelessly to TouchDesigner on the computer. I managed to get OSC messages over to TouchDesigner when the 33 IoT board was connected to the computer via a USB cable, but when I plugged it into another power source to test it out without any physical connection to computer, it didn't work. When the board is powered from another source, I am not sure if the Arduino is connecting to the WiFi router since I cannot check on the Serial Monitor now.

I might be missing something really important here..

Here is the code for this, as I said I mixed some library examples from WifiNINA and OSC Library (I left some print functions out):

#include <SPI.h>
#include <WiFiNINA.h>
#include <WiFi.h>
#include <WiFiUdp.h>
#include <SPI.h>3
#include <OSCMessage.h>


// WIFI
#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;        // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)
int status = WL_IDLE_STATUS;     // the WiFi radio's status

WiFiUDP Udp;

//the Arduino's IP
IPAddress ip(192, 168, 0, 100);
//destination IP
IPAddress outIp(192, 168, 0, 101);

const unsigned int outPort = 7000;    // local port to listen on

int count = 0;

void setup() {

  Udp.begin(8080);

  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  // you're connected now, so print out the data:
  Serial.print("You're connected to the network");


}


void loop() {

  //delay(100);
  printCurrentNet();

  //the message wants an OSC address as first argument
  OSCMessage msg("/Acc1");
  msg.add(int32_t(count));
  msg.add(int32_t(count+180));
  msg.add(int32_t(count+360));

  
  Udp.beginPacket(outIp, outPort);
    msg.send(Udp); // send the bytes to the SLIP strea
  Udp.endPacket(); // mark the end of the OSC Packet
  
  msg.empty(); // free space occupied by message  
  delay(100);

  count++;

  Serial.print("working");
  

}

I would really appreciate if someone could set some light on what am I missing here.

In the meantime I will be checking out MQTT :slight_smile:

Thanks guys :heart:

which library did you use?

You need to comment the while(!Serial). This line will stop the sketch until the Serial Monitor or Plotter window is opened.

Always the usual suspects...

1 Like

Yippeee Ka Yayyy Mother Lovers :heart:

@Klaus_K that was it. Makes sense now, that it didn't run before launching Serial with that line :slight_smile:, thanks for sorting that usual suspect haha

I popped my Arduino wireless data-transfer cherry today. Thank you all for directing me and helping me with the code :heart:

@J-M-L I am using a library Named OSC by Adrian Freed

I will still check out the MQTT since I need to increase the number of boards transferring data to the computer, but this is a very good start.