LXSAMD21DMX library for SAMD21

Questions concerning any LXSeries open source projects.
Comments and requests can also be posted on GitHub.
xldaedalus
Posts: 17
Joined: Wed Jun 22, 2022 10:18 pm

LXSAMD21DMX library for SAMD21

Postby xldaedalus » Wed Jun 22, 2022 10:46 pm

I'm new to C++ but have been designing and programming Lighting hardware for 10+ years. I'm trying learn some new things and add bluetooth, wifi etc to mix and get away from MPLab. I'm attempting to to build a small DMX/RDM prototype board using the SAMD21 DEV Breakout board. It has a SAMD21G18.
I just downloaded the LXSAMD21DMX-master.zip library into the Arduino IDE. I attempted to compile the RDMSerialRecv.ino: Sample RDM application. Any help would be greatly appreciated

I get the following error(s) at UID.h:46:1: error: expected class-name before '{' token

Line 46 in UID.h ==. class UID: public Printable {

Looking this up, its usually an error of finding a pre-defined element, in this case "Printable"

I tried the following

--> In UID.h includes as per original

#include <stdint.h>
#include <String.h>
#include <Print.h>
// for Arduino SAMD 32bit Cortex M0 boards package prior to 1.8.10 use
//#include <WString.h>
//#include <Printable.h>

--> OR in UID.h includes including both Print and Printable

#include <stdint.h>
#include <String.h>
#include <Print.h>
// for Arduino SAMD 32bit Cortex M0 boards package prior to 1.8.10 use
#include <WString.h>
#include <Printable.h>

----------------- FOLLOWING ERROR ----------------------------------------------------
Arduino: 1.8.16 (Mac OS X), Board: "Arduino Zero (Native USB Port)"

In file included from /Users/leeparker/Documents/Arduino/libraries/LXSAMD21DMX-master/src/LXSAMD21DMX.h:60:0,
from /Users/leeparker/Documents/Arduino/libraries/LXSAMD21DMX-master/src/LXSAMD21DMX.cpp:16:
/Users/leeparker/Documents/Arduino/libraries/LXSAMD21DMX-master/src/rdm/UID.h:46:1: error: expected class-name before '{' token
{
^
exit status 1
Error compiling for board Arduino Zero (Native USB Port).


--> OR in UID.h includes including ONLY <WString.h> and <Printable.h>


#include <stdint.h>
//#include <String.h>
//#include <Print.h>
// for Arduino SAMD 32bit Cortex M0 boards package prior to 1.8.10 use
#include <WString.h>
#include <Printable.h>


----------------- FOLLOWING ERROR ----------------------------------------------------
Arduino: 1.8.16 (Mac OS X), Board: "Arduino Zero (Native USB Port)"

In file included from /Users/leeparker/Documents/Arduino/libraries/LXSAMD21DMX-master/src/LXSAMD21DMX.h:60:0,
from /Users/leeparker/Documents/Arduino/libraries/LXSAMD21DMX-master/src/LXSAMD21DMX.cpp:16:
/Users/leeparker/Documents/Arduino/libraries/LXSAMD21DMX-master/src/rdm/UID.h:46:1: error: expected class-name before '{' token
{
^
/Users/leeparker/Documents/Arduino/libraries/LXSAMD21DMX-master/src/rdm/UID.h:136:28: error: 'Print' has not been declared
virtual size_t printTo(Print& p) const;
^~~~~
exit status 1
Error compiling for board Arduino Zero (Native USB Port).

admin
Site Admin
Posts: 148
Joined: Mon Nov 20, 2017 4:31 pm

Re: LXSAMD21DMX library for SAMD21

Postby admin » Thu Jun 23, 2022 2:29 pm

I'm not sure which version of the Arduino SAMD library you are using (use Boards Manager... to find out). But, for 1.8.13, Printable.h and WString.h are deprecated, use Arduino.h instead. This correction has been pushed to git. Or, keep what you have and just change UID.h to

Code: Select all

 #include Arduino.h
.

xldaedalus
Posts: 17
Joined: Wed Jun 22, 2022 10:18 pm

Re: LXSAMD21DMX library for SAMD21

Postby xldaedalus » Fri Jun 24, 2022 12:43 am

I am using Arduino 1.8.13. The Sparkfun SAMD21 DEV Breakout board appears as an Arduino Zero. I deleted the old LXSAMD21 library and downloaded and re-installed the updated library from GitHub. Now it compiles!

Thanks for doing that. Now to figure out how to get the serial ports working correctly. The Sparkfun Dev Board has three serial ports by default - SerialUSB, Serial (Port 0 {30,31}) and Serial1 (Port 1 {0,1}), and I will be using them all, as the device I'm working on will be a bit like what is called an "Opti" in the business (for Optical Isolator). I'm not yet using actual isolation - yet - but I will be re-transmitting data from other ports.

I see in LXSAMD21DMX.h line 521

#elif defined ( ARDUINO_SAMD_ZERO )
#define use_optional_sercom_macros 1. //<-- Sets Rx Tx on pins 4 3 SERCOM2:0 SERCOM2:1

You use
// --mostly to enable support for https://www.sparkfun.com/products/15110

#define PIN_DMX_RX (0ul)
#define PIN_DMX_TX (1ul)
Which would get me Rx Tx on D0 and D1 of the Sparkfun, but what does "1ul" mean, when "D1" = PA10 = pin 19 on the chip? This is one of the frustrating parts of the Arduino IDE. A lot of the necessary data is hidden in a folder on the MAC. Searching for pin.h or spi.h shows no hidden file results, though I imagine there somewhere. Obviously, "ul" is defined somewhere to reference a "pin" number related to the board being used that links it to the actual pin on the processor. Trying to figure that out.

I will continue to post what I learn so my learning will help others use your code. As I expand it, if you are interested in my contributions, I'm happy to share. But, as I'm still learning, my work may not be the best. ;)

I have a question. As I am using an SPI OLED graphics display, I know that it can take a long time to update the display. In the end, I think I'd like to use a DMA channel to shift out the entire OLED buffer, to keep the MAIN loop cycle fast as possible. The display as it is less important than responding to RDM and handling DMX frames in a speedy manner. It might also be nice to use DMA for re-transmitting the DMX frames. I don't yet know much about how to set up DMA channels on the SAMD21, but I will be working on it. To that end, you have any suggestions for example code that would work with the LXSAMD21 library, your ideas would be appreciated.

Thank you very much for what you've done so far. You work getting me started is very much appreciated.

xldaedalus
Posts: 17
Joined: Wed Jun 22, 2022 10:18 pm

Re: LXSAMD21DMX library for SAMD21

Postby xldaedalus » Fri Jun 24, 2022 1:04 am

I added this macro to LXSAMD21DMX.h

#elif ( use_optional_sercom_macros == 6 )

//********************** optional sercom macros 6 **********************
// Arduino Zero Port 0 aka Serial.xxx calls go to this port Port 1 aka Serial1.xxx calls go to pins D0,D1
// SerialUSB.xxx calls go to the USB port and the "Serial Monitor function of the Arduino
#define PIN_DMX_RX (31ul)
#define PIN_DMX_TX (30ul)
#define PAD_DMX_RX SERCOM_RX_PAD_3
#define PAD_DMX_TX UART_TX_PAD_2

// Set to PIO_SERCOM or PIO_SERCOM_ALT
#define MUX_DMX_RX PIO_SERCOM_ALT
#define MUX_DMX_TX PIO_SERCOM_ALT

// SERCOMn is pointer to memory address where SERCOM registers are located.
#define DMX_SERCOM SERCOM5

// sercomN is C++ wrapper for SERCOMn (passed to UART constructor)
#define DMX_sercom sercom5

// sercom handler function
#define DMX_SERCOM_HANDLER_FUNC SERCOM5_Handler

#warning Using use_optional_sercom_macros = 6
.
I get the same error if I use ( use_optional_sercom_macros == 4 ) - which is already in the LXSAMD21DMX.h. If I use ( use_optional_sercom_macros == 1 ) the code compiles correctly. I think this means "SERCOM5_Handler" is not defined?

The option_sercom_macro 4 has these comments
//********************** optional sercom macros 4 **********************
// --replaces Serial1 on MKR1000
// --requires commenting out lines 178 to 186 in. <----------------
// Arduino15/packages/arduino/hardware/samd/1.8.4/variants/mkr1000/variant.cpp
// otherwise Serial1 will conflict on Sercom5 and this won't compile

For my package // Arduino15/packages/arduino/hardware/samd/1.8.3/variants/Sparkfun_SAMD21_Dev/variant.cpp 170-174

// 30..41 - Extra Pins
// ----------------------
// 30/31 - Extra UART
{ PORTB, 22, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // 30/TX: SERCOM5/PAD[2]
{ PORTB, 23, PIO_SERCOM_ALT, PIN_ATTR_NONE, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_NONE }, // 31/RX: SERCOM5/PAD[3]

210-220 read
Uart Serial1( &sercom0, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX ) ;
Uart Serial( &sercom5, PIN_SERIAL_RX, PIN_SERIAL_TX, PAD_SERIAL_RX, PAD_SERIAL_TX ) ;

void SERCOM0_Handler()
{
Serial1.IrqHandler();
}

void SERCOM5_Handler()
{
Serial.IrqHandler();
}

*** I get this compile error ***

/Users/leeparker/Library/Arduino15/packages/arduino/hardware/samd/1.8.13/variants/arduino_zero/variant.cpp:230: multiple definition of `SERCOM5_Handler'
libraries/LXSAMD21DMX-master/LXSAMD21DMX.cpp.o:/Users/leeparker/Documents/Arduino/libraries/LXSAMD21DMX-master/src/LXSAMD21DMX.cpp:38: first defined here
collect2: error: ld returned 1 exit status
exit status 1
Error compiling for board Arduino Zero (Native USB Port).

Thanks.

admin
Site Admin
Posts: 148
Joined: Mon Nov 20, 2017 4:31 pm

Re: LXSAMD21DMX library for SAMD21

Postby admin » Fri Jun 24, 2022 4:40 pm

Is there a question? You need to comment out the SERCOM5_Handler function in the variants file if you want to use it in LXSAMD21DMX as is stated in the comments. It was included as an option for a situation where other pin configurations were in use and someone wanted a way to use SERCOM5. A better choice is to use another peripheral. See the microcontroller data sheet for the table of options.

This article explains the basics of SAMD21 peripherals: https://learn.adafruit.com/using-atsamd ... xing-it-up

xldaedalus
Posts: 17
Joined: Wed Jun 22, 2022 10:18 pm

Re: LXSAMD21DMX library for SAMD21

Postby xldaedalus » Sat Jun 25, 2022 12:59 am

Yes, sorry if I am verbose. I assume someday, someone like me will run across these posts and will appreciate detail

Yes, I had a question. You use "pin(31ul)" in your definitions in LXSAMD21DMX.h. I've looked for the meaning of "ul" appended to the pin number and I can't find what it means exactly. I assume it means the pin number as defined by the board package instead of the actual MCU pin name "PB23".

The pins I need are defined by the RS485 shield with 2 transceivers I designed and made which includes a Timo FX chip that switches the DMX input pins to the Timo if it is on. Complications. SERCOM5 as RxTx as Serial.xxx() standard on this board. Serial1.xx() uses D1, D0 as standard. and SerialUSB.xx() is used for the Arduino Serial Monitor. I thought it would be easier to use the standard defined pins.

OK, I got my code changes to compile RDMDevicetest.ino with the following change not using the Sparkfun assigned definition of the SERCOM5_Handler use_optional_sercom_macros is defined
(running Arduino 1.8.16 (latest version as of 6/24/22) but version 1.8.3 of the SAMD21_Dev)

/Users/leeparker/Library/Arduino15/packages/SparkFun/hardware/samd/1.8.3/variants/SparkFun_SAMD21_Dev/variant.cpp

#fdef use_optional_sercom_macros //if you use any of the optional SERCOM for DMX

// For LXSAMD21DMX - SERCOM5_Handler() is defined elsewhere
// Note: if compiling other projects, and those project use .h files with this #def -- you might get an error

#else

// otherwise use as per the SpSparkFun_SAMD21_Dev intended

void SERCOM5_Handler()
{
Serial.IrqHandler();
}

#endif

For novices like me, this is a hidden file. To find it on MAC, click Finder/Go, when the drop down menu appears, press the Option key. A new choice will appear called "Library". Here you will find Arduino15(possibly depending on which version of Arduino you have installed) and all the #includes located in <path>

It is advised to make a backup copy of any file here, and rename it variant_orig.cpp, for example, BEFORE making changes and saving them. Otherwise you could end up re-installing everything.

Now to see if it works with RDM! I will be testing with the City Theatrical DMXcat which can poll for RDM devices on a universe.

admin
Site Admin
Posts: 148
Joined: Mon Nov 20, 2017 4:31 pm

Re: LXSAMD21DMX library for SAMD21

Postby admin » Sat Jun 25, 2022 5:28 pm

ul is unsigned long. In c++ it is sometimes desirable (or necessary) to distinguish the type of a numeric constant for the compiler when you are calling a function.

When identifying pin designations, it is sometimes necessary to refer to the schematic of the board. In general Arduino standardizes pin numbers and these are defined in the board definition's files. But, if you are looking at the microcontroller documentation, it may be necessary to delve into the pins.h file or look at the schematic to translate a designation like PB23 (or port b pin 23) into the corresponding Arduino pin number.

xldaedalus
Posts: 17
Joined: Wed Jun 22, 2022 10:18 pm

Re: LXSAMD21DMX library for SAMD21

Postby xldaedalus » Mon Jul 04, 2022 10:09 pm

For unknown reason, the Sparkfun Dev Board is an "Arduino Zero". Serial Monitor is normally Serial.print. On the Sparkfun, Serial.print prints to pins 30,31 - the pins need to have connected to SerialDMX. Serial1.print prints to D0, D1 and SerialUSB.print prints to the USB. The latter is the standard for printing to the serial monitor.

Obviously none of the tests work - yet. I've confirm DIRECTION_PIN, Pins 30, 31 are connected to the correct pins on the RS485 transceiver an that it outputs as it should. I have to go through the LXSAMD21DMX library and change all calls to serial.print to serialUSB.print.

SerialUSB.begin(115200);
while (!SerialUSB)
{
; // wait for SerialUSB port to connect. Needed for native USB port only
}

Is there a better way to swap the output function of Serial Monitor without having to change all serial.print calls and choose at will which serial port I want to use for Serial Monitor. Starting SerialUSB is a bit different that starting serial.print.

I apologize if this is a dumb question. Thanks for your help.

xldaedalus
Posts: 17
Joined: Wed Jun 22, 2022 10:18 pm

Re: LXSAMD21DMX library for SAMD21

Postby xldaedalus » Tue Jul 05, 2022 7:29 pm

Ok, I got everything compiling. Hardware checks out Tx=30 Rx=31 DIRECTION_PIN (DMX_RE/DE) = 14. I can see RDM requests being input into the RX pin on the SAMD21.

RDMDeviceTest does nothing. No RDM ID is returned. No serial data of any kind is being reported by the serial debug monitor.

I set DIRECTION_PIN as OUTPUT and set is HIGH (receive mode) in setup(). About 600mS after compiling, I see the DIRECTION_PIN go low (Tx Mode). But it stays LOW (it can't receive if the transceiver is in Tx Mode, so receiving nothing is no surprise.

Obviously, I've had to make some very minor changes to the code with respect to use_optional_sercom_macros there is a conflict issue with the definition of SERCOM5_Handler() in variant vs LXSAMD21DMX.

How do I confirm I have SERCOM5 on 30,31 set up on the right pads, the SERCOM5 interrupt handler is running correctly?

In Debug SerialUSB.print(PIO_SERCOM); returns 2 and SerialUSB.print(PIN_DMX_RX); returns 5 so, perhaps the macro use_optional_sercom_macros isn't setting up SERCOM the properly?

How to I confirm DIRECTION_PIN is being set properly? In theory DIRECTION_PIN should always default to the HIGH state in a DMX device.

Thanks

xldaedalus
Posts: 17
Joined: Wed Jun 22, 2022 10:18 pm

Re: LXSAMD21DMX library for SAMD21

Postby xldaedalus » Tue Jul 05, 2022 8:38 pm

I found the issue. The wrong hardware was being defined by the Arduino IDE, and using the standard Arduino-Zero variant.cpp instead of the Sparkfun Dev Board Arduino Zero variant.cpp. I fixed the by commenting out the definition of the SERCOM5_Handler() in the standard Arduino Zero variant.cpp line 230.

I am at least receiving DMX RDM discovery request. I receive 3 attempts, although the DMXcat is sending requests about 1 per second.

uint8_t cmdclass = rdmdata[RDM_IDX_CMD_CLASS];
uint16_t pid = (rdmdata[RDM_IDX_PID_MSB] << 8 ) | rdmdata[RDM_IDX_PID_LSB];

#ifdef SERIAL_DEBUG // <-----------------------------------DEBUG----
SerialUSB.print("cmdclass ");
SerialUSB.println(cmdclass);
SerialUSB.print("pid ");
SerialUSB.println(pid);
#endif

cmdclass 16
pid 3

cmdclass 16
pid 1

cmdclass 16
pid 2

Not sure why I get different PIDs but at lease I'm receiving. The adventure will continue in week or so