Modifying library for the WSSFM10 Sigfox module for compatibility with STM32L476RG

All about boards manufactured by ST
luka.banfi
Posts: 10
Joined: Fri Dec 11, 2020 3:09 pm

Modifying library for the WSSFM10 Sigfox module for compatibility with STM32L476RG

Post by luka.banfi »

Arduino IDE version 1.8.13 installed.

Selected options:
  • Board: "Nucleo-64"
  • Board part number: "Nucleo L476RG"
  • U(S)ART support: "Enabled (generic 'Serial')"
  • USB support (if available): "None"
  • USB speed (if available): "Low/Full Speed"
  • Optimize: "Smallest (-Os default)"
  • C Runtime Library: "Newlib Nano (default)"
  • Upload method: "Mass Storage"
  • Port: "COM3"
A while ago I purchased this kit. The product site has a link to the Arduino library for the WSSFM10 Sigfox module. I'm struggling modifying the library to achieve compatibility with STM32L476RG. The BRKWS01 Sigfox board requires TX, RX, 3.3 V and GND connections.Image TX (BRKWS01) is connected to RX/D0 (PA_3) and RX (BRKWS01) is connected to TX/D1 (PA_2) on STM32L476RG. Image IoThings_WSSFM10_Demo.ino:

Code: Select all

/***************************************************************************
  This is a library for the Wisol 10 module 

  Designed to work with all kinds of WSSFM10R Breakout Boards

  This module use UART, 2 pins are required to interface.

  Written by Adrien Chapelet for IoThings
 ***************************************************************************/

#include "IO_WSSFM10.h"

IO_WSSFM10 mySigfox(10, 11, true);

typedef struct {
  int counter;
  int light;
  float temp;
} Payload;

int counter=0;
  
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
    pinMode(LED_BUILTIN, OUTPUT);
    mySigfox.begin();
    delay(50);
    mySigfox.test();
    mySigfox.getID();
    mySigfox.getPAC();
    mySigfox.getTemp();

    //mySigfox.setPowerMode(1);
}
  
// the loop function runs over and over again forever
void loop() {  
  String sfResponse;
  Payload p;
  p.counter = counter;
  p.light = analogRead(A1);
  p.temp = analogRead(A2);
  bool statusS = mySigfox.send(&p, sizeof(p));
  if (statusS) counter++;

  delay(60000);
  bool statusSR = mySigfox.sendReceive(&p, sizeof(p), sfResponse);
  if (statusSR) {
    for (uint8_t i= 0; i<26; ++i) {//RX= 01 02 03 04 05 06 07 08
      Serial.println(sfResponse[i]);
      counter++;
    }
  }
}
IO_WSSFM10.h:

Code: Select all

/***************************************************************************
  This is a library for the Wisol 10 module 

  Designed to work with all kinds of WSSFM10R Breakout Boards

  This module use UART, 2 pins are required to interface.

  Written by Adrien Chapelet for IoThings
 ***************************************************************************/

#ifndef __IO_WSSFM10_H__
#define __IO_WSSFM10_H__

//#include <inttypes.h>
//#include "String.h"
#include "Arduino.h"
#include <SoftwareSerial.h>
//#include "SoftSerialSTM32.h"

#define LED_BUILTIN 13

class IO_WSSFM10
{
	protected:
	// Instance-specific properties

	public:
		//IO_WSSFM10(void);
		//IO_WSSFM10(uint8_t rxPin, uint8_t txPin);
		IO_WSSFM10(uint8_t rxPin, uint8_t txPin, bool debugEn);

		String test(void);

		void blink(void);
		void begin(void);
		String getData(void);

		String getID(void);
		String getPAC(void);

		//uint16_t getTemp(void);
		uint16_t getTemp(void);
		String setPowerMode(uint8_t mode);
		String setOutputPower(uint8_t power);
		void wakeUp(void);

		bool send(const void* data, uint8_t size);
		bool sendReceive(const void* data, uint8_t size, String response);

		bool sendString(String str);
		bool sendReceiveString(String str, String response);
		/*int8_t getRev();
		bool setPower(uint8_t power);*/

		String _nextReturn();

		typedef enum {
			OK,
			KO,
			SENT
		} Status;

		bool debug;

	private:
		uint8_t rx, tx;
		//SoftSerialSTM32 Sigfox;
		SoftwareSerial Sigfox;
		//#if defined(__STM32F1__)
		//  HardwareSerial *port;
		//#endif
};

extern IO_WSSFM10 WSSFM10;

#endif
IO_WSSFM10.cpp:

Code: Select all

/***************************************************************************
  This is a library for the Wisol 10 module 
  Designed to work with all kinds of WSSFM10R Breakout Boards
  This module use UART, 2 pins are required to interface.
  Written by Adrien Chapelet for IoThings
 ***************************************************************************/

#include "IO_WSSFM10.h"

//IO_WSSFM10 WSSFM10;

//Message buffer
uint8_t msg[12];

/*IO_WSSFM10::IO_WSSFM10 () : Sigfox(), debug(1) {
	//Sigfox(rxPin, txPin, 3);
}*/

/*IO_WSSFM10::IO_WSSFM10 (uint8_t rxPin, uint8_t txPin) : rx(rxPin), tx(txPin), debug(0) {
	Sigfox(rxPin, txPin, 3);
}*/

IO_WSSFM10::IO_WSSFM10 (uint8_t rxPin=10 , uint8_t txPin=11, bool debugEn=true) : Sigfox(rxPin, txPin), debug(debugEn) {
	//Sigfox(rxPin, txPin);
}

//IO_WSSFM10::IO_WSSFM10 (uint8_t rxPin, uint8_t txPin, bool debugEn) : Sigfox(rxPin, txPin, 3), debug(debugEn) {
//}


void IO_WSSFM10::blink(){
	digitalWrite(LED_BUILTIN, 1);   // turn the LED on (HIGH is the voltage level)
	delay(50);                       // wait for a second
	digitalWrite(LED_BUILTIN, 0);    // turn the LED off by making the voltage LOW
	delay(50);
}

String IO_WSSFM10::getData(){
	String data = "";
	char output;

	while (!Sigfox.available()){
		blink();
	}

	while(Sigfox.available()){
		output = Sigfox.read();
		if ((output != 0x0A) && (output != 0x0D)){//0x0A Line feed | 0x0D Carriage return
			data += output;
    	}

		delay(10);
	}	

	if(debug){
		Serial.print("Data: ");
		Serial.println(data);
	}

	return data;
}

String IO_WSSFM10::test(){
	Sigfox.print("AT\r");
	String status = getData();

	if(debug){
		Serial.print("Status: ");
		Serial.print(status);
	}

	return status;
}

void IO_WSSFM10::begin(){
	//pinMode(rxPin, INPUT);
	//pinMode(txPin, OUTPUT);
	Sigfox.begin(9600);

	if (debug) {
		Serial.begin(9600);
		delay(100);
		getID();
		delay(100);
		getPAC();
	}
}

//Get Sigfox ID
String IO_WSSFM10::getID(){
	Sigfox.print("AT$I=10\r");
	String id = getData();

	if(debug){
		Serial.print("ID: ");
		Serial.println(id);
	}

	return id;
}


//Get PAC number
String IO_WSSFM10::getPAC(){
	Sigfox.print("AT$I=11\r");
	String pac = getData();

	if(debug){
		Serial.print("PAC: ");
		Serial.println(pac);
	}

	return pac;
}

uint16_t IO_WSSFM10::getTemp(void){
	Sigfox.print("AT$T?\r");

	uint16_t tempVal = getData().toInt();

	if(debug){
		Serial.println("Module temperature: ");
		Serial.println(tempVal);
	}

	return tempVal;
}

String IO_WSSFM10::setPowerMode(uint8_t mode){
//0: Software reset
//1: sleep, send a break to wake up
//2: deep_sleep, toggle GPIO0 or Reset_N to wake up

	Sigfox.print("AT$P=");
	Sigfox.print(mode);
	Sigfox.print("\r");
	String res = getData();

	if(debug){
		Serial.println("Power Mode response: ");
		Serial.println(res);
	}

	return res;
}

String IO_WSSFM10::setOutputPower(uint8_t power){
	Sigfox.print("ATS302=");
	Sigfox.print(power);
	Sigfox.print("\r");
	String res = getData();

	if(debug){
		Serial.println("Output Power response: ");
		Serial.println(res);
	}

	return res;
}

void IO_WSSFM10::wakeUp(void){
	Sigfox.print("\r");
}

//Send Sigfox Message
bool IO_WSSFM10::send(const void* data, uint8_t size){//const void* data
	uint8_t* bytes = (uint8_t*)data;

	Sigfox.print("AT$SF=");
	char tmp[3] = {0}; // 2 hex characters + null terminator
	if(debug){
		Serial.print("Bytes:");
	}
	for(uint8_t i= 0; i<size; ++i){
		sprintf(tmp, "%02X", bytes[i]);
		Sigfox.print(tmp);
		if(debug){
			Serial.print(tmp);
		}
	}
	if(debug){
		Serial.println();
	}

	Sigfox.print("\r");

	while (!Sigfox.available()){
		blink();
	}

	String res = getData();

	if(res.indexOf("OK") >= 0) {
		Serial.println("Message successfully sent");
		return true;
	}
	
	if(debug){
		Serial.print("Status: ");
		Serial.println(res);
	}
	return false;
}

bool IO_WSSFM10::sendString(String str) {
	if(debug){
		Serial.print("Message:");
		Serial.println(str);
	}

	Sigfox.print("AT$SF=");
	Sigfox.print(str);
	Sigfox.print("\r");

  	while (!Sigfox.available()){
		blink();
	}

	String res = getData();

	if(res.indexOf("OK") >= 0) {
		Serial.println("Message successfully sent");
		return true;
	}
	
	if(debug){
		Serial.print("Status: ");
		Serial.println(res);
	}
	return false;
}



bool IO_WSSFM10::sendReceive(const void* data, uint8_t size, String response){
	uint8_t* bytes = (uint8_t*)data;
	Sigfox.print("AT$SF=");
	char tmp[3] = {0}; // 2 hex characters + null terminator
	if(debug){
		Serial.print("Bytes:");
	}
	for(uint8_t i= 0; i<size; ++i){
		sprintf(tmp, "%02X", bytes[i]);
		Sigfox.print(tmp);
		if(debug){
			Serial.print(tmp);
		}
	}
	if(debug){
		Serial.println();
	}

	Sigfox.print(",1\r");

	while (!Sigfox.available()){
		blink();
	}

	String res = getData();

	if(res.indexOf("OK") >= 0) {
		Serial.println("Message successfully sent");
		response = getData();
		return true;
	}
	
	if(debug){
		Serial.print("Status: ");
		Serial.println(res);
	}
	return false;
}


bool IO_WSSFM10::sendReceiveString(String str, String response) {
	Sigfox.print("AT$SF=");
	Sigfox.print(str);
	Sigfox.print(",1\r");

	while (!Sigfox.available()){
		blink();
	}

	String res = getData();

	if(res.indexOf("OK") >= 0) {
		Serial.println("Message successfully sent");
		response = getData();
		return true;
	}
	
	if(debug){
		Serial.print("Status: ");
		Serial.println(res);
	}
	return false;
}
Your assistance in this matter would be greatly appreciated.
by paulportohernan » Tue Jan 05, 2021 4:23 pm
i have upload a new example for STM32L476RG to the library in case anyone need this:

Code: Select all

#include <Tinyfox.h>

#define btn   PC13 // boton usuario azul / blue user button
#define RXLED  PA5
#define rstPin PC12


//nucleo-64 STM32L476RG:

//HardwareSerial Serial2(USART2);
HardwareSerial Serial3(USART3);
Tiny<HardwareSerial,HardwareSerial> wisol(&Serial3,&Serial,rstPin,false);

void setup() {
  pinMode(btn,INPUT_PULLUP);
  pinMode(RXLED,OUTPUT);
  
  Serial.begin(115200);
  Serial.println("");
  Serial.println("boot");
  wisol.begin(9600);

  while(!Serial);  //comentar si usará una fuente de energía externa

 Serial.println("-Presione botón PC13-");
}

void loop() {
  
  if(digitalRead(btn)==0){

    digitalWrite(RXLED,LOW);
    Serial.println("Tx");
    wisol.RST();
    
    uint32_t valor =10;
    Serial.println(wisol.SEND(valor));
    
    //String valor_recibido = wisol.SEND_RCV(valor); //aproximandamente esperar 1 minuto    
    //Serial.println(valor_recibido); 
    
    digitalWrite(RXLED,HIGH);
    wisol.SLEEP();
    delay(3000);
    Serial.println("-Presione botón PC13-");
  }
  
}
Go to full post
paulportohernan
Posts: 10
Joined: Sun Dec 20, 2020 4:32 pm
Answers: 1

Re: Modifying library for the WSSFM10 Sigfox module for compatibility with STM32L476RG

Post by paulportohernan »

a friend and i wrote a library for the wisol modules. we call it TinyFox. the blue pill example should be compatible with minimal modifications
you can find it here: https://github.com/TECA-IOT/Tinyfox
or at the library manager : )

just change
HardwareSerial Serial2(USART2); //this is the default serial in the l476rg
HardwareSerial Serial3(USART3); //you could use this for the moduel
Tiny<HardwareSerial,HardwareSerial> wisol(&Serial3,&Serial2,PA1,false); // first goes the module port then the debug port, the reset pin and false to disable debug mode.
luka.banfi
Posts: 10
Joined: Fri Dec 11, 2020 3:09 pm

Re: Modifying library for the WSSFM10 Sigfox module for compatibility with STM32L476RG

Post by luka.banfi »

paulportohernan wrote: Sat Jan 02, 2021 9:21 pm a friend and i wrote a library for the wisol modules. we call it TinyFox. the blue pill example should be compatible with minimal modifications
you can find it here: https://github.com/TECA-IOT/Tinyfox
or at the library manager : )

just change
HardwareSerial Serial2(USART2); //this is the default serial in the l476rg
HardwareSerial Serial3(USART3); //you could use this for the moduel
Tiny<HardwareSerial,HardwareSerial> wisol(&Serial3,&Serial2,PA1,false); // first goes the module port then the debug port, the reset pin and false to disable debug mode.
I received a compilation error:

Code: Select all

Arduino: 1.8.13 (Windows 10), Board: "Nucleo-64, Nucleo L476RG, Mass Storage, Enabled (generic 'Serial'), None, Low/Full Speed, Smallest (-Os default), Newlib Nano (default)"

c:/users/banfi/appdata/local/arduino15/packages/stm32/tools/xpack-arm-none-eabi-gcc/9.2.1-1.1/bin/../lib/gcc/arm-none-eabi/9.2.1/../../../../arm-none-eabi/bin/ld.exe: C:\Users\banfi\AppData\Local\Temp\arduino_cache_911289\core\core_236afafeca7b73cab1cd7267b3d029a9.a(HardwareSerial.cpp.o):(.bss.Serial2+0x0): multiple definition of `Serial2'; sketch\Tiny_BluePill_stm32xxx.ino.cpp.o:(.bss.Serial2+0x0): first defined here

collect2.exe: error: ld returned 1 exit status

exit status 1

Error compiling for board Nucleo-64.



This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
If I comment

Code: Select all

//HardwareSerial Serial2(USART2);
it compiles, but the only output I get in the serial monitor is "boot" and "-Presione botón PA4-", because the if condition (digitalRead(btn)==0) in loop() is not met. I receive the same output if I change

Code: Select all

HardwareSerial Serial2(USART2);
to

Code: Select all

HardwareSerial Serial4(USART2);
and change

Code: Select all

Tiny<HardwareSerial,HardwareSerial> wisol(&Serial3,&Serial2,PA1,false);
to

Code: Select all

Tiny<HardwareSerial,HardwareSerial> wisol(&Serial3,&Serial4,PA1,false);
Tiny_BluePill_stm32xxx.ino:

Code: Select all

#include <Tinyfox.h>

#define btn   PA4
#define RXLED  PC13


//bluepill f103c8:
HardwareSerial Serial2(USART2);
HardwareSerial Serial3(USART3);
Tiny<HardwareSerial,HardwareSerial> wisol(&Serial3,&Serial2,PA1,false);

void setup() {
  pinMode(btn,INPUT_PULLUP);
  pinMode(RXLED,OUTPUT);
  
  Serial.begin(115200);
  Serial.println("");
  Serial.println("boot");
  wisol.begin(9600);

  while(!Serial);  //comentar si usará una fuente de energía externa

 Serial.println("-Presione botón PA4-");
}

void loop() {
  
  if(digitalRead(btn)==0){

    digitalWrite(RXLED,LOW);
    Serial.println("Tx");
    wisol.RST();
    
    uint32_t valor =10;
    //Serial.println(wisol.SEND(valor));
    
    String valor_recibido = wisol.SEND_RCV(valor); //aproximandamente esperar 1 minuto    
    Serial.println(valor_recibido); 
    
    digitalWrite(RXLED,HIGH);
    wisol.SLEEP();
    delay(3000);
    Serial.println("-Presione botón PA4-");
  }
  
}
paulportohernan
Posts: 10
Joined: Sun Dec 20, 2020 4:32 pm
Answers: 1

Re: Modifying library for the WSSFM10 Sigfox module for compatibility with STM32L476RG

Post by paulportohernan »

try this configuration:

HardwareSerial Serial3(USART3); //connect the modulo to serial3.
Tiny<HardwareSerial,HardwareSerial> wisol(&Serial3,&Serial,PA1,false); //change PA1 to match your reset pin.
.
.
.
#define btn PC13 //change this to PC13 the blue/user button on the nucleo
#define RXLED PA5
...
if(digitalRead(btn)==0){ //hold the user/blue button to trigger the transmission

this should work. if it those i will add this as an example for l476rg.
luka.banfi
Posts: 10
Joined: Fri Dec 11, 2020 3:09 pm

Re: Modifying library for the WSSFM10 Sigfox module for compatibility with STM32L476RG

Post by luka.banfi »

paulportohernan wrote: Sun Jan 03, 2021 4:25 pm try this configuration:

HardwareSerial Serial3(USART3); //connect the modulo to serial3.
Tiny<HardwareSerial,HardwareSerial> wisol(&Serial3,&Serial,PA1,false); //change PA1 to match your reset pin.
.
.
.
#define btn PC13 //change this to PC13 the blue/user button on the nucleo
#define RXLED PA5
...
if(digitalRead(btn)==0){ //hold the user/blue button to trigger the transmission

this should work. if it those i will add this as an example for l476rg.
How do I determine my reset pin (change PA1 to match your reset pin)? I have 4 connections in total: 3.3 V, GND, TX (BRKWS01) is connected to RX/D0 (PA_3) and RX (BRKWS01) is connected to TX/D1 (PA_2) on STM32L476RG. Am I missing an additional connection for the RST pin of the BRKWS01 Sigfox board?

I got the following output after ~5 minutes:

Code: Select all

boot
-Presione botón PA5-
Tx
AT$SF=0000000a,1

-Presione botón PA5-
Tiny_BluePill_stm32xxx.ino:

Code: Select all

#include <Tinyfox.h>

#define btn   PC13
#define RXLED  PA5


//bluepill f103c8:
HardwareSerial Serial3(USART3);
Tiny<HardwareSerial,HardwareSerial> wisol(&Serial3,&Serial,PA1,false);

void setup() {
  pinMode(btn,INPUT_PULLUP);
  pinMode(RXLED,OUTPUT);
  
  Serial.begin(115200);
  Serial.println("");
  Serial.println("boot");
  wisol.begin(9600);

  while(!Serial);  //comentar si usará una fuente de energía externa

 Serial.println("-Presione botón PA5-");
}

void loop() {
  
  if(digitalRead(btn)==0){

    digitalWrite(RXLED,LOW);
    Serial.println("Tx");
    wisol.RST();
    
    uint32_t valor =10;
    //Serial.println(wisol.SEND(valor));
    
    String valor_recibido = wisol.SEND_RCV(valor); //aproximandamente esperar 1 minuto    
    Serial.println(valor_recibido); 
    
    digitalWrite(RXLED,HIGH);
    wisol.SLEEP();
    delay(3000);
    Serial.println("-Presione botón PA5-");
  }
  
}
paulportohernan
Posts: 10
Joined: Sun Dec 20, 2020 4:32 pm
Answers: 1

Re: Modifying library for the WSSFM10 Sigfox module for compatibility with STM32L476RG

Post by paulportohernan »

in your module you have a reset pin beside the Vcc pin (marked in blue in the graphic). connect that to the nucleo board on some free pin.
this pin its necessary to wake up the module after its put in sleep mode
load the code and push the user button.
BRKWS01.png
BRKWS01.png (74.66 KiB) Viewed 5596 times
luka.banfi
Posts: 10
Joined: Fri Dec 11, 2020 3:09 pm

Re: Modifying library for the WSSFM10 Sigfox module for compatibility with STM32L476RG

Post by luka.banfi »

paulportohernan wrote: Sun Jan 03, 2021 7:12 pm in your module you have a reset pin beside the Vcc pin (marked in blue in the graphic). connect that to the nucleo board on some free pin.
this pin its necessary to wake up the module after its put in sleep mode
load the code and push the user button.
BRKWS01.png
I tried with several different pins (PA10, PB5, PA8, PB3) and modified the code accordingly, but I always get the same output as before:

Code: Select all

-Presione botón PA5-
Tx
AT$SF=0000000a,1

-Presione botón PA5-
paulportohernan
Posts: 10
Joined: Sun Dec 20, 2020 4:32 pm
Answers: 1

Re: Modifying library for the WSSFM10 Sigfox module for compatibility with STM32L476RG

Post by paulportohernan »

you dont get the message on the sigfox backend? are you sure the module its connected to the right Tx and Rx pins? your modules have leds to let you know when its transmitting?
also, you are using the

Code: Select all

 wisol.send_rcv()
funtion, if you dont have a downlink configured use

Code: Select all

wisol.send()
luka.banfi
Posts: 10
Joined: Fri Dec 11, 2020 3:09 pm

Re: Modifying library for the WSSFM10 Sigfox module for compatibility with STM32L476RG

Post by luka.banfi »

paulportohernan wrote: Sun Jan 03, 2021 9:59 pm you dont get the message on the sigfox backend? are you sure the module its connected to the right Tx and Rx pins? your modules have leds to let you know when its transmitting?
also, you are using the

Code: Select all

 wisol.send_rcv()
funtion, if you dont have a downlink configured use

Code: Select all

wisol.send()
I commented out:

Code: Select all

//String valor_recibido = wisol.SEND_RCV(valor); //aproximandamente esperar 1 minuto    
//Serial.println(valor_recibido);
and uncommented:

Code: Select all

Serial.println(wisol.SEND(valor));
Apparently the module wasn't connected to the right TX and RX pins, because I received no message in the Sigfox backend when TX (BRKWS01) was connected to RX/D0 (PA_3) and RX (BRKWS01) was connected to TX/D1 (PA_2), so I switched it so that TX (BRKWS01) is connected to D2 (PA_10) and RX (BRKWS01) is connected to D6 (PB_10). I received messages: Image
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

Re: Modifying library for the WSSFM10 Sigfox module for compatibility with STM32L476RG

Post by fpiSTM »

Hi,
on Nucleo L476RG D0 and D1 are not connected by default:
D0D1L476RG.png
D0D1L476RG.png (9.24 KiB) Viewed 5556 times
SB 62/63 are opened by default as PA2 and PA3 are used by the STLink.
Post Reply

Return to “STM boards (Discovery, Eval, Nucleo, ...)”