Giga R1 Wifi: I installed micropython and Arduino C+, how can I get them to work together?

I have a Giga R1 Wifi.

I configured Arduino C+ code for Wifi, NTP, and USB. It will generate the IP address. When I open the micropython IDE, it will no longer connect. Can you point me to the documentation on getting both processors to work with C+ and Micropython?

/* This sketch has the minimum requirements for
Wifi Configuration
NTP Configuration
USB Configuration
*/

// #include <Wire.h>

// WiFi
#include <WiFi.h>

// NTP
#include <mbed_mktime.h>

// USB Drive
#include <FATFileSystem.h>
#include <Arduino_USBHostMbed5.h>
#include "arduino_secrets.h"

int status = WL_IDLE_STATUS;
WiFiUDP Udp;
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 keyIndex = 0;              // your network key index number (needed only for WEP)
unsigned int localPort = 123;  // local port to listen for UDP packets
constexpr auto timeServer{ "tock.usno.navy.mil" };
const int NTP_PACKET_SIZE = 48;      // NTP timestamp is in the first 48 bytes of the message
byte packetBuffer[NTP_PACKET_SIZE];  // buffer to hold incoming and outgoing packets

void setup() {
  Serial.begin(115200);
  // put your setup code here, to run once:
  WifiConfig();        // Call the Wifi functions to create the connection
  printWifiStatus();   // Print the Wifi connection specs
  setNtpTime();        // Setup NTP Time from Naval Time Clock
  USB_Mount();         // Mount USB and write a file
}

void loop() {

}


// Call the Wifi functions to create the connection
void WifiConfig() {
  while (status != WL_CONNECTED) {
    status = WiFi.begin(ssid, pass);
    delay(2000);
  }
  Serial.println("Connected to WiFi");
}

// Setup NTP Time from Naval Time Clock
void setNtpTime() {
  Udp.begin(localPort);
  sendNTPpacket(timeServer);
  delay(1000);
  parseNtpPacket();
  Serial.print("UTC System Clock: ");
  Serial.println(getLocaltime());
}

// Print the Wifi Status to Serial Monitor and in the future to OLED/LCD screens
void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  IPAddress gateway = WiFi.gatewayIP();
  Serial.print("Gateway: ");
  Serial.println(gateway);
  IPAddress dns_0 = WiFi.dnsIP(0);
  IPAddress dns_1 = WiFi.dnsIP(1);

  Serial.print("DNS Address: ");
  Serial.print(dns_0);
  Serial.print(", ");
  Serial.println(dns_1);
  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
  Serial.println(" ");
}

// This is the configuration for retriving the NTP information
unsigned long sendNTPpacket(const char* address) {
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  packetBuffer[0] = 0b11100011;  // LI, Version, Mode
  packetBuffer[1] = 0;           // Stratum, or type of clock
  packetBuffer[2] = 6;           // Polling Interval
  packetBuffer[3] = 0xEC;        // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12] = 49;
  packetBuffer[13] = 0x4E;
  packetBuffer[14] = 49;
  packetBuffer[15] = 52;

  Udp.beginPacket(address, 123);  // NTP requests are to port 123
  Udp.write(packetBuffer, NTP_PACKET_SIZE);
  Udp.endPacket();
}

// This parses out the string of the NTP Packet for printing
unsigned long parseNtpPacket() {
  if (!Udp.parsePacket())
    return 0;

  Udp.read(packetBuffer, NTP_PACKET_SIZE);
  const unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
  const unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
  const unsigned long secsSince1900 = highWord << 16 | lowWord;
  constexpr unsigned long seventyYears = 2208988800UL;
  const unsigned long epoch = secsSince1900 - seventyYears;
  set_time(epoch);
}

// This sets up the buffer and parses out the string into a printable formate
String getLocaltime() {
  char buffer[32];
  tm t;

  _rtc_localtime(time(NULL), &t, RTC_FULL_LEAP_YEAR_SUPPORT);
  strftime(buffer, 32, "%a %Y-%m-%d %H:%M:%S", &t);

  return String(buffer);
}


void USB_Mount() {
  USBHostMSD msd;
  mbed::FATFileSystem usb("usb");
  pinMode(PA_15, OUTPUT);  //enable the USB-A port
  digitalWrite(PA_15, HIGH);


  Serial.println("Starting USB Dir List example...");

  // if you are using a Max Carrier uncomment the following line
  // start_hub();

  while (!msd.connect()) {
    //while (!port.connected()) {
    delay(1000);
  }

  Serial.print("Mounting USB device... ");
  int err = usb.mount(&msd);
  if (err) {
    Serial.print("Error mounting USB device ");
    Serial.println(err);
    while (1)
      ;
  }
  Serial.println("done.");
  Serial.println(" ");

  char buf[256];

  // Display the root directory
  Serial.print("Opening the root directory... ");
  DIR* d = opendir("/usb/");
  Serial.println(!d ? "Fail :(" : "Done");
  if (!d) {
    snprintf(buf, sizeof(buf), "error: %s (%d)\r\n", strerror(errno), -errno);
    Serial.print(buf);
  }
  Serial.println("done.");

  Serial.println("Root directory:");
  unsigned int count{ 0 };
  while (true) {
    struct dirent* e = readdir(d);
    if (!e) {
      break;
    }
    count++;
    snprintf(buf, sizeof(buf), "    %s\r\n", e->d_name);
    Serial.print(buf);
  }
  Serial.print(count);
  Serial.println(" files found!");

  snprintf(buf, sizeof(buf), "Closing the root directory... ");
  Serial.print(buf);
  fflush(stdout);
  err = closedir(d);
  snprintf(buf, sizeof(buf), "%s\r\n", (err < 0 ? "Fail :(" : "OK"));
  Serial.print(buf);
  if (err < 0) {
    snprintf(buf, sizeof(buf), "error: %s (%d)\r\n", strerror(errno), -errno);
    Serial.print(buf);
  }
  Serial.println(" ");

  Serial.print("mount done ");
  mbed::fs_file_t file;
  struct dirent* ent;
  int dirIndex = 0;
  int res = 0;
  Serial.println("Open /usb/numbers/integer.txt");
  FILE* f = fopen("/usb/numbers/integer.txt", "w+");
  for (int i = 0; i < 10; i++) {
    Serial.print("Writing numbers (");
    Serial.print(i);
    Serial.println("/10)");
    fflush(stdout);
  }
  Serial.println("File closing");
  fflush(stdout);
  Serial.println("File closed");
  Serial.println(" ");
}

Output:

Connected to WiFi
SSID: xxxxxxxxxxxxxxxx
IP Address: 192.168.40.16
Gateway: 192.168.40.173
DNS Address: 1.0.0.1, 1.1.1.1
signal strength (RSSI):-43 dBm

UTC System Clock: Thu 2024-03-28 00:09:04

Starting USB Dir List example...
Mounting USB device... done.
Opening the root directory... Done
done.

Root directory:
System Volume Information
1 files found!
Closing the root directory... OK

mount done Open /usb/numbers/integer.txt

Writing numbers (0/10)
Writing numbers (1/10)
Writing numbers (2/10)
Writing numbers (3/10)
Writing numbers (4/10)
Writing numbers (5/10)
Writing numbers (6/10)
Writing numbers (7/10)
Writing numbers (8/10)
Writing numbers (9/10)
File closing
File closed

I run WifiFirmwareUpdater to get the Arduino side working. I am still researching how to install Micropython on the other processor.

To the best of my knowledge, you can either use the Arduino C++ IDE to compile and upload programs to the board, OR install the Micropython interpreter. You cannot do both at the same time.

https://docs.arduino.cc/tutorials/giga-r1-wifi/giga-micropython/

One installed, MicroPython uses its own method to upload python scripts to the board. If you are using an IDE like for example Thonny, this will make its own serial connection with the board. An attempt to make another connection at the same time from, say, the Arduino IDE will find the port already busy and fail to connect.

According to Dronebot Workshop, the Giga has two cores you can run Arduino on one and Micropython on the second

Arm Cortex M7 480 Mhz Core
Arm Cortex M4 240 Mhz Core

I am checking with them.

That is interesting and this article does indeed confirm the presence of an M7 and M4 core that can be programmed separately:

https://docs.arduino.cc/tutorials/giga-r1-wifi/giga-dual-core/

I had seen references indicating that the STM32H747XI is dual core, but didn't realise that they are different cores. The article does mention the ability to program each core separately, although the M4 core has to be enabled first. Memory has to be partitioned with a quantity allocated to each. Theoretically MicroPython could "live" on one of those partitions. However it seems that both cores share the same UART and GPIO pins, which would be interesting to program as one would need to carefully segregate GPIO pin usage between the cores. Whereas there is some indication in the article as to how one goes about selecting which core a sketch is uploaded to, it doesn't mention working with MicroPython.

This post is also related to ypur question and suggests that MicroPythin would be run on the M7 core and the Arduino sketch on the M4, but the process activating the M4 core from MicroPython is still under development.

1 Like

The only issue I ever had with Arduino is they never lay out how to use every feature of their devices.

RPC allows the M4 and M7 to communicate. They show OTA, Over the Air, as a feature. I wonder how that would work to program each core. Could you assign a IP address to each core? When will the ability to use all these functions exist? Even Dronebot Workshop said many of the functions haven't been brought over from the Portenta H7 yet. Maybe I get a Protenta H7? I want to get a RPi 5 to go with my 4B.

https://docs.arduino.cc/tutorials/giga-r1-wifi/giga-micropython/
Following the steps below will install MicroPython on the M7 core.

Hi! You'll find there what you need to make the Giga R1 works with MicroPython and the Arduino Code on both cores :slight_smile: