Arduino NANO 33 IOT - SoftwareSerial problem

Hey

I have a set up with:

Arduino UNO
Whadda WPI430 GPS MODULE U-BLOX NEO-7M

It works perfect. It is using #include <VMA430_GPS.h>

and VMA430 is using

#include "Arduino.h"
#ifdef __AVR__
  #include <SoftwareSerial.h>
#endif

SoftwareSerial

This is working fine on UNO.

I would like to use Nano 33 IOT in the project. I need to use IOT to see GPS data and alarms. It is a boat project - Anchor Alarm. With warning on my phone.

Nano 33 IOT have, I think, different serial ports and IDE board manager "Nano 33 IOT" is not supported by VMA430_GPS.h

Any suggestions to use VMA430_GPS.h with Nano 33 IOT?? Or find another solution with this Whadda WPI430 GPS MODULE U-BLOX NEO-7M?


#include <VMA430_GPS.h>     // Include the GPS module library
#include <SoftwareSerial.h> // Include the software serial library

// Display DOWN
#include <Adafruit_GFX.h>       // include Adafruit graphics library
#include <Adafruit_ILI9341.h>   // include Adafruit ILI9341 TFT library
 
#define TFT_CS    8      // TFT CS  pin is connected to arduino pin 8
#define TFT_RST   9      // TFT RST pin is connected to arduino pin 9
#define TFT_DC    10     // TFT DC  pin is connected to arduino pin 10
// initialize ILI9341 TFT library
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// Display UP

// RX fra GPS forbindes til pin 2 - TX fra GPS forbindes til pin 3 - ALTSĂ… OMVENDT AF HVAD MAN SKULLE TRO
SoftwareSerial ss(3, 2); // RX, TX

The problem is that RX and TX is different om the Nano 33 IOT.

You're leaving out at least one important line of code, the call to the constructor.

VMA430_GPS has two constructors, one for SoftwareSerial and one for HardwareSerial; use the latter. I'm not familiar with the Nano33 IoT but I think that the below will do instead of whatever we can't see.

VMA430_GPS gps(&Serial1);

Why even try to use SoftwareSerial with the Nano 33 IOT when it has a hardware UART (serial port) named Serial1 on pins 0 and 1 that is independent of the USB serial connection unlike the UNO ?

I am using this line I my code

VMA430_GPS gps(&ss);
#include <VMA430_GPS.h>     // Include the GPS module library
#include <SoftwareSerial.h> // Include the software serial library

// Display DOWN
#include <Adafruit_GFX.h>       // include Adafruit graphics library
#include <Adafruit_ILI9341.h>   // include Adafruit ILI9341 TFT library
 
#define TFT_CS    8      // TFT CS  pin is connected to arduino pin 8
#define TFT_RST   9      // TFT RST pin is connected to arduino pin 9
#define TFT_DC    10     // TFT DC  pin is connected to arduino pin 10
// initialize ILI9341 TFT library
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
// Display UP

// RX fra GPS forbindes til pin 2 - TX fra GPS forbindes til pin 3 - ALTSĂ… OMVENDT AF HVAD MAN SKULLE TRO
SoftwareSerial ss(3, 2); // RX, TX

VMA430_GPS gps(&ss);     // Pass the softwareserial connection info the the GPS module library

You mean to replace my line with the one below.

And then move the wire from the GPS pin 2 RX and pin 3 TX on the UNO to

pin 1 TX and pin 2 RX on the Nano 33 IOT

VMA430_GPS gps(&Serial1);

That sounds right but I have no experience with the library that you are using

Thanks

Tried it, but I get this error message:

WARNING: library WPI430-VMA430_GPS claims to run on avr architecture(s) and may be incompatible with your current board which runs on samd architecture(s).

Seems like the VMA430_GPS don't like samd architecture.

Maybe I need another library driver. But I can't find it anywhere.

If any one have found a VMA430_GPS library for SAM D21 familie architecture, please let me know :slight_smile:

the boar info:

BN: Arduino NANO 33 IoT
VID: 2341
PID: 8057
SN: 45393DA550593730372E3120FF022F27

SAM D21 Family

The board's main processor is a low power Arm® Cortex®-M0 32-bit SAMD21. The WiFi and Bluetooth® connectivity is performed with a module from u-blox, the NINA-W10, a low power chipset operating in the 2.4GHz range. On top of those, secure communication is ensured through the Microchip® ECC608 crypto chip. Besides that, you can find a 6 axis IMU, what makes this board perfect for simple vibration alarm systems, pedometers, relative positioning of robots, etc.

Because I want to use

VMA430_GPS.h

For my GPS module. And its using SoftSerial. I don't know how to go around that and use the hardware port.

And one more reason for using the Nano 33 IOT.

My display QVGA 2.2 TFT SPI 240*320 runs on 3.3 v - same as the Nano 33 IOT

It's a warning; I would say, try it out.

Note:
Except for what you showed, I do not immediately see a reason why it would only run on AVR.

Some library authors have the philosophy of "I'm only going to specify the architectures I test for" even when there is nothing architecture-specific in their code. So I also think it is worth trying it out.

The ideal is that the low level architecture specific code is wrapped in the standardized Arduino APIs by the core, and then libraries and sketches that use that API exclusively are portable to any board

Hi @pegholm

The Arduino Nano 33 IoT is based on the SAMD21 microcontroller. The SAMD21 doesn't have an implementation of the SoftwareSerial library, because it's possible to create additional hardware Serial ports from the microcontroller's spare Serial Communication (SERCOM) modules, that can be configured as either Serial, SPI or I2C ports:

The easiest approach would be to replace the SoftwareSerial object "ss" with Serial1, in your GPS library and use the Nano 33 IoT's standard hardware TX and RX pins. If you're using more than one Serial port then follow the instructions in the Adafruit tutorial above to create additional ones.

Tried it - it do not run.
It fails and stops the upload.

the library code looks like this:

/*************************************************** 

 ****************************************************/

#include "Arduino.h"
#ifdef __AVR__
  #include <SoftwareSerial.h>
#endif

#define GPS_DEBUG

enum NavMode { Pedestrian, Automotive, Sea, Airborne };
enum DataRate { F1Hz, F2Hz, F3_33Hz, F4Hz };

struct UBX_msg {
  byte class_byte;
  byte id_byte;
  uint16_t payload_length;
  byte* msg;
  byte CK_A;
  byte CK_B;
  };

struct Time_UTC {
  uint16_t year;
  uint8_t month;
  uint8_t day;
  uint8_t hour;
  uint8_t minute;
  uint8_t second;
  bool valid = false;
};

struct Location {
  double longitude = 0.0;
  double latitude = 0.0;
  bool valid = false;
};


#define NAV_MODE_PEDESTRIAN 0x03
#define NAV_MODE_AUTOMOTIVE 0x04
#define NAV_MODE_SEA 0x05
#define NAV_MODE_AIRBORNE 0x06

#define DATA_RATE_1HZ 0xE803
#define DATA_RATE_2HZ 0xFA01
#define DATA_RATE_3_33HZ 0x2C01
#define DATA_RATE_4HZ 0xFA00

#define PORT_RATE_4800 0xC01200
#define PORT_RATE_9600 0x802500
#define PORT_RATE_19200 0x004B00
#define PORT_RATE_38400 0x009600
#define PORT_RATE_57600 0x00E100
#define PORT_RATE_115200 0x00C200
#define PORT_RATE_230400 0x008400

#define UBX_SYNC_1 0xB5
#define UBX_SYNC_2 0x62

// definition of UBX class IDs
// source: U-blox7 V14 Receiver Description Protocol page 88 https://www.u-blox.com/sites/default/files/products/documents/u-blox7-V14_ReceiverDescriptionProtocolSpec_%28GPS.G7-SW-12001%29_Public.pdf
#define NAV_CLASS 0x01 // Navigation Results: Position, Speed, Time, Acc, Heading, DOP, SVs used
#define RXM_CLASS 0x02 // Receiver Manager Messages: Satellite Status, RTC Status
#define INF_CLASS 0x04 // Information Messages: Printf-Style Messages, with IDs such as Error, Warning, Notice
#define ACK_CLASS 0x05 // Ack/Nack Messages: as replies to CFG Input Messages
#define CFG_CLASS 0x06 // Configuration Input Messages: Set Dynamic Model, Set DOP Mask, Set Baud Rate, etc
#define MON_CLASS 0x0A // Monitoring Messages: Comunication Status, CPU Load, Stack Usage, Task Status
#define AID_CLASS 0x0B // AssistNow Aiding Messages: Ephemeris, Almanac, other A-GPS data input
#define TIM_CLASS 0x0D // Timing Messages: Time Pulse Output, Timemark Results
#define LOG_CLASS 0x21 // Logging Messages: Log creation, deletion, info and retrieval

class VMA430_GPS {
 public:
#ifdef __AVR__
  VMA430_GPS(SoftwareSerial *);
#endif
  VMA430_GPS(HardwareSerial *);

  void begin(int32_t baudrate);
  void getconfig(void);
  bool getUBX_packet(void);
  void setUBXNav(void);
  bool parse_ubx_data(void);
  
  NavMode NavigationMode = Pedestrian;
  DataRate DataRefreshRate = F4Hz;
 
  bool GLLSentence;
  bool GSASentence;
  bool GSVSentence;
  bool RMCSentence;
  bool VTGSentence;

  byte buffer_msg[60];

  Time_UTC utc_time;
  Location location;

  


  
 private: 
	byte* generateConfiguration(void);
	void sendConfiguration(void);
	void receive(void);
	void calcChecksum(byte *, byte);
	void sendUBX(byte *, byte);
  bool parse_ubx_nav_data(void);

  bool parse_nav_timeutc(void);
  bool parse_nav_pos(void);
  
	byte getUBX_ACK(byte *);
  uint32_t extractLong(uint8_t, byte*);
  int32_t extractSignedLong(uint8_t, byte*);
	
	long portRate;
	Stream *stream = NULL;
	HardwareSerial *hwSerial = NULL; 
  UBX_msg latest_msg;
#ifdef __AVR__	
	SoftwareSerial *swSerial = NULL;
#endif
};

it looks like there are a hardware possibility for none AVR: ??
Some of the code from above.

#ifdef __AVR__
  #include <SoftwareSerial.h>
#endif


#ifdef __AVR__
  VMA430_GPS(SoftwareSerial *);
#endif
  VMA430_GPS(HardwareSerial *);

just don't know how to rewrite the library code. It is not obvious for me :frowning:

can not find the Arduino.h library om my Mac.

maybe it contains some thing to change.

Anyone knows where is is hidden?

Arduino.h is not the right place to make changes. It should always be possible to make things work from the sketch or library. At least for the problem you have.

Have you tried the suggestion in reply #11?

Like:

VMA430_GPS gps(&Serial1);     // Pass the hardware serial connection info the the GPS module library

yes I tried that and keeps getting this error:

pep_Helium_AnkerAlarm_v5_2.2-IOT:40:17: error: 'Serial1' was not declared in this scope
 VMA430_GPS gps(&Serial1);
                 ^~~~~~~
/Users/peregholm/Documents/Arduino/pep_Helium_AnkerAlarm_v5_2.2-IOT/pep_Helium_AnkerAlarm_v5_2.2-IOT.ino:40:17: note: suggested alternative: 'Serial'
 VMA430_GPS gps(&Serial1);
                 ^~~~~~~
                 Serial
exit status 1
'Serial1' was not declared in this scope

Where do I declare that?

In the code of in the VMA430_GPS.h

Are you sure you have the right board selected in the Tools menu?

When you post an error message, enable all compiler warnings, and post the entire message not just a snippet

Absolutely not. it replaces the line

VMA430_GPS gps(&ss);     // Pass the softwareserial connection info the the GPS module library

in your sketch. Does it not look familiar?

Hi @pegholm

I managed to get the VMA430_GPS example to compile for the Nano 33 IoT.

The issue is that the SAMD21 Arduino core code implements the SerialX (C++) objects as a class called Uart, while the AVR core code implements them as a class called HardwareSerial.

The first step is to do what @anon57585045 suggested and pass the address of Serial1 as an argument to the VMA430_GPS constructor, in the example code:

#include <VMA430_GPS.h>     // Include the GPS module library
//#include <SoftwareSerial.h> // Include the software serial library

//SoftwareSerial ss(3, 2); // RX, TX
VMA430_GPS gps(&Serial1);     // Pass the softwareserial connection info the the GPS module library

The next step is to modify the VMA430_GPS.h and VMA430_GPS.cpp files replacing the constructor's HardwareSerial* parameter with Uart*:

VMA430_GPS.h line 39:

//VMA430_GPS(HardwareSerial *);
VMA430_GPS(Uart *);

VMA430_GPS.cpp line 21:

//VMA430_GPS::VMA430_GPS(HardwareSerial *ss)
VMA430_GPS::VMA430_GPS(Uart *ss)

After making these changes the code compiles, however unfortunately I'm unable to test, as I don't have a Nano 33 IoT or a VMA430 GPS to hand.