Programming the Lepton from start to finish

12v to 28v, it’s written on the silk screen between the input power leads

You can go down to 10V, but it’s not recommended.

The aux power already has 3v and if you connect to the debugger 3v you get a problem. If you only program the board without powering it up then you must connect the 3v power to the debugger to power the MCU. However double-powering is not allowed unless you want to see smoke.

Cheers,
Valentine

I actually did double power it accidentally and the stlink started blinking but it still seems to work ok.

Ok, double powering is a good explanation, thought.

I checked with the oscilloscope, the microcontroller is not printing anything out of the uart. So it’s not my arduino serial pass through that’s the problem. Any ideas on why my code doesn’t work/how to get it working? I definitely need to be able to communicate with the chip over serial to do anything.

I can’t see between the power leads after putting the 1000 uf capacitor on, but good that it’s on there.

I increased the delay to 1000, I don’t know why you use _delay most of the time. I forgot that delay is in milliseconds in arduino. In micropython it’s sleep() and it’s in seconds (but you can have floating point numbers in there)

also I don’t know why I didn’t just use the mosquito, something about 3 pin pwm instead of 6 maybe.

_delay doesn’t work, btw, it says it’s not defined and gives a compilation error

nope, even this doesn’t work:

void setup() {

Serial.setRx(PA15);

Serial.setTx(PA2);

Serial.begin(38400);

}

void loop() {

Serial.println(“test”);

delay(1000);

}

I think maybe the pins Deku mentioned are wrong?hm no from the schematic looks right. Probably no problem with the board. Says it was programmed.

reading stuff like this: https://github.com/stm32duino/Arduino_Core_STM32/issues/1637 Are you sure I don’t have to do anything to get the system to execute the code or anything? It says something about start command completed successfully and sounds like it may have started executing the program after being programmed. Not clear. Not clear if it does so automatically upon reboot either. I was assuming it works like an arduino, after being programmed with the arduino ide, maybe not. Maybe there is a bootloader built into the arduino ide I can use. Maybe that’s not useful or not applicable or not needed… much uncertainty. This is the sort of thing I thought would happen, this is why I started well ahead of time and asked for exact details, which I appreciate the details thus far, but it appears that something is missing yet.

That should work. The first 4 lines of my setup() are

  Serial.setRx(UART2_RX);
  Serial.setTx(UART2_TX);
  Serial.begin(115200);
  Serial.println(F_CPU);

And it does print 64000000, so that should work as the entire program. Make sure you have the same baud rate selected in arduino serial monitor as you use in the program.

The clock code does not go in setup. Copy/paste the whole function SystemClock_Config from my earlier post. The function only has to exist, and it will be called by the arduino/stm32 library sometime earlier in the bootup process.

To check if it’s running at all, you can use any of the connector pins as an indicator. For example toggle PB7 off and on every second or whatever, and touch a voltmeter to GND and the SDA pin on the I2C connector to watch it change (obviously don’t call Wire.begin when doing this test)

I agree with you Valentine.

The SWD interface 3.3V is an output, not an input.
The STLink expects to receive the MCU’s voltage on its 3.3V pin. that’s why it’s called Vtarget… it does not supply the MCU with power on this line. It’s only dubious clone STlinks that supply power on this pin.

I recommend to get a proper STLink V3 Mini, they aren’t expensive. This will also support Serial TTL 2 USB conversion.

"C:\Users\anthony\AppData\Local\Temp.arduinoIDE-unsaved2023114-5856-18ujnwc.kck4\sketch_feb14a\sketch_feb14a.ino: In function ‘void setup()’:
C:\Users\anthony\AppData\Local\Temp.arduinoIDE-unsaved2023114-5856-18ujnwc.kck4\sketch_feb14a\sketch_feb14a.ino:44:14: error: ‘UART2_RX’ was not declared in this scope; did you mean ‘USART2_IRQn’?
44 | Serial.setRx(UART2_RX);
| ^~~~~~~~
| USART2_IRQn
C:\Users\anthony\AppData\Local\Temp.arduinoIDE-unsaved2023114-5856-18ujnwc.kck4\sketch_feb14a\sketch_feb14a.ino:45:16: error: ‘UART2_TX’ was not declared in this scope; did you mean ‘UART_IT_TXE’?
45 | Serial.setTx(UART2_TX);
| ^~~~~~~~
| UART_IT_TXE

exit status 1

Compilation error: ‘UART2_RX’ was not declared in this scope; did you mean ‘USART2_IRQn’?"

When running:

void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

/** Configure the main internal regulator output voltage
*/
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);

/** Initializes the RCC Oscillators according to the specified parameters

  • in the RCC_OscInitTypeDef structure.
    */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
    RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
    RCC_OscInitStruct.PLL.PLLN = 8;
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
    RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
    RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
    Error_Handler();
    }

/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}

void setup() {
Serial.setRx(UART2_RX);
Serial.setTx(UART2_TX);
Serial.begin(38400);
Serial.println(F_CPU);
pinMode(PB7, OUTPUT);
}

void loop() {
// put your main code here, to run repeatedly:
Serial.println(F_CPU);
delay(1000);
digitalWrite(PB7, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(PB7, LOW);
}

Could it be that the arduino ide is not configured correctly? It doesn’t know enough to connect the name of the pin, maybe there is other stuff missing too and that’s part of the problem.

edit:
ok I was able to get the SDA pin to toggle by changing the uart pins to PA whatever as Deku had mentioned previously, thanks Deku for the suggestion. However it stops, apparently the whole thing crashes, the instant I connect the tx line of the STM32 to the RX of the arduino mega. Everything is grounded correctly apparently. I have no idea why it would do this.

@Anthony_Douglas

Please check this thread it may help

There was no need to obtain any new files or copy them in any specific place, the softwareserial thing is in the library of the arduino IDE.

To recap for the programing of the STM32: – Get the connectors, I got a kit with precrimped connectors. -Get an stlink. I got the V2 which is apparently actually a knockoff and not an original device, and does not include a ttl level shifter for serial comminication. There is the 2.1 version which apparently does but no gaurantees.

  • get the boards, details to come on that later, but suffice it to say for now that you can use the EasyEDA links, open the board in the editor and there is a way to repeat exactly the same order, it feeds the three ifles into the JLCB system, or you can feed the files in manually, it wasn’t as cantankerous as I thought it would be, was actually pretty easy.
    -install both STMcube IDE and STMcube programmer software. They are not the same, I have no idea if one includes the other, I just installed both.
    -use the board manager in Arduino to add the url for the boards, there are many instructions for this, it is approximately like this bu thte url given ther emay not be the best one, there is the main repo and then there is one being passed around for some random spinoff Setting up Arduino IDE for STM32 - Simuli
    -select the right chip and board. tools’> board → generic STM32G0, then select tools->board part number ->031k8Ux
    -Then make sure in tools-> upload method the SWD upload thing is selected.
    -connect the St-link to the board, don’t connect any other power source or the regulators in the st-link and on the board could fight each other or you can not connect the 3.3 volts to the ST-link, but pick one. Fortunately my st-link device was resistant to back-pwering and just blinks if back powered and apparently doesn’t draw any current as the regulators could be fighting each other. Maybe there is a diode in there or something. This doesn’t mean it could not cause problems in another circumstance, if the voltage regulators were slightly different.
    probably it is best to adopt the standard approach of not powering the device with the st-link, in case the board changes and this becomes a problem, you are feeding voltage in the wrong side of a regulator when you power things with the st-link I guess, it wasn’t a problem but I guess it could be.

-now you should be able to upload arduino code. It takes a solid 2 minutes to compile sometimes, I don’t know why it is so slow.

  • You can use the code snippets above to test things, it prints something out the serial port and also toggles the SDA pin of the I2C port.

Now, on to actually trying out the Simplefoc code/trying to get that working :slight_smile:

oops the actual code, I thought I pasted it already:
serial pass through for mega:

/*

SerialPassthrough sketch

Some boards, like the Arduino 101, the MKR1000, Zero, or the Micro, have one

hardware serial port attached to Digital pins 0-1, and a separate USB serial

port attached to the IDE Serial Monitor. This means that the "serial

passthrough" which is possible with the Arduino UNO (commonly used to interact

with devices/shields that require configuration via serial AT commands) will

not work by default.

This sketch allows you to emulate the serial passthrough behaviour. Any text

you type in the IDE Serial monitor will be written out to the serial port on

Digital pins 0 and 1, and vice-versa.

On the 101, MKR1000, Zero, and Micro, “Serial” refers to the USB Serial port

attached to the Serial Monitor, and “Serial1” refers to the hardware serial

port attached to pins 0 and 1. This sketch will emulate Serial passthrough

using those two Serial ports on the boards mentioned above, but you can change

these names to connect any two serial ports on a board that has multiple ports.

created 23 May 2016

by Erik Nyquist

*/

void setup() {

Serial.begin(38400);

Serial1.begin(38400);

}

void loop() {

if (Serial.available()) { // If anything comes in Serial (USB),

Serial1.write(Serial.read());   // read it and send it out Serial1 (pins 0 & 1)

}

if (Serial1.available()) { // If anything comes in Serial1 (pins 0 & 1)

Serial.write(Serial1.read());   // read it and send it out Serial (USB)

}

}
to get the STM32 to print to serial with software serial, which as Runger notes is not a good approach when actually using the system, but as I note is better than nothing for now:


#include "SoftwareSerial.h"

#define SS_USB_RX  PA15
#define SS_USB_TX  PA2

// ANY OTHER SOFT SERIAL BAUD RATE WILL CHOKE
// BAUD RATE MUST BE BETWEEN 9600..38400
// ANY OTHER BAUD RATE WILL CHOKE

SoftwareSerial SoftSerialUSB(SS_USB_RX, SS_USB_TX);

void setup()
{
  //set pins for Software Serial communication
  SoftSerialUSB.begin(38400);
  pinMode(SS_USB_RX, INPUT);
  pinMode(SS_USB_TX, OUTPUT);

  delay(1000);
}

void loop()
{
  SoftSerialUSB.println("TEST SSERIAL_USB");
  delay(100);
}

The code for the stm32 to toggle stuff, the serial is commented out, it doesn’t work yet :slight_smile:

void setup() {
 Serial.setRx(PA15);
 Serial.setTx(PA2);
   Serial.begin(38400);
   Serial.println(F_CPU);
   pinMode(PB7, OUTPUT);
 }
 
 void loop() {
   // put your main code here, to run repeatedly:
 //Serial.println(F_CPU);
 delay(1000);
   digitalWrite(PB7, HIGH);  // turn the LED on (HIGH is the voltage level)
   delay(1000);                      // wait for a second
   digitalWrite(PB7, LOW);
 }

Just create a file build_opt.h with a text editor, place it in your local project directory and paste this inside

-D ENABLE_HWSERIAL1 -D ENABLE_HWSERIAL2 -D ENABLE_HWSERIAL3

These are part of your project and specific to your build, they are not part of any formal git repo.

It may be really helpful for you to read formally about the Arduino IDE and build environments and C/C++ embedded environments in general.

Cheers,
Valentine

Yes, my knowledge on the subject is pretty weak, I generally avoid arduino and appreciate the help… I also believe that not everyone can know everything and that it’s important to package things up as a foundation that can be stood upon. Hopefully all this will help evolve the project to the point where you don’t need to know how to program an STM32 in order to get your motor working… it give an error:

At least I can use software serial to get on with some stuff.

Are you sure this encoder works with simplefoc? it’s the sc60228DC. I thought you prescribed one that was known to work, but the thread on the subject indicates it’s not quite ready yet:

I’m trying to use the code snippets in that thread to see if I can at least read angle values from the chip. I have it connected in place with a magnet on the fan. So far, apparently the source code has errors which confuse the simpleFOC directory with the simpleFOC_drivers directory. I have been copying files to where it appears to expect to find them so I can carry on … compiling now, I don’t know why this latest version of arduino takes so long to do everything…

update: ok I hit a dead end again. It keeps being unable to find the files that need to be connected, the header files etc. The simpleFOC folders and SimpleFOC_drivers folders got mixed up at some point, or the files used to all be under simpleFOC and when they were separated something went wrong. The files still refer to the old directory structure. I tried correcting the files and that fixes the error for one but it keeps invoking endless more that it doesn’t even need to refer to, I can’t correct them all only to find out it still doesn’t work. If I try to merge the directory structures copies are produced and it gives errors about multiple copies of the same file.

The errors all look like this:
In file included from c:\Users\anthony\Documents\Arduino\libraries\SimpleFOCDrivers\src\encoders\aeat8800q24\MagneticSensorAEAT8800Q24.cpp:1:
c:\users\anthony\documents\arduino\libraries\simplefocdrivers\src\encoders\aeat8800q24\magneticsensoraeat8800q24.h:5:10: fatal error: common/base_classes/Sensor.h: No such file or directory
5 | #include “common/base_classes/Sensor.h”
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.

exit status 1

Compilation error: exit status 1

They can be corrected by copying …/…/Simple_FOC/src/ before the name.

ok I got things to compile by merging the directories

I tire this code, to check the angle sensor. Probably I mucked something up althoguh it’s not clear if the driver etc. is good to go yet.

#include “SoftwareSerial.h”

#include <SimpleFOCDrivers.h>

#include “encoders/sc60228/MagneticSensorSC60228.h”

// SENSOR SPI SC60228

// SPI2 PINS

#define CSN2 PA4

#define CLK2 PA5

#define MISO2 PB4

#define MOSI2 PB5

#define SS_USB_RX PA15

#define SS_USB_TX PA2

// BAUD RATE MUST BE BETWEEN 9600…38400

// ANY OTHER BAUD RATE WILL CHOKE

SoftwareSerial SoftSerialUSB(SS_USB_RX, SS_USB_TX);

MagneticSensorSC60228 sensorSC60228(CSN2);

SPIClass SPISensor(MOSI2, MISO2, CLK2);

void setup()

{

//set pins for Software Serial communication

SoftSerialUSB.begin(38400);

pinMode(SS_USB_RX, INPUT);

pinMode(SS_USB_TX, OUTPUT);

sensorSC60228.init(&SPISensor);

delay(1000);

}

void loop()

{

SoftSerialUSB.println(“TEST SSERIAL_USB”);

Serial.print(">> ");

Serial.println(sensorSC60228.getAngle());

sensorSC60228.update();

delay(100);

}

it prints the “TEST SSERIAL_USB” about 8 times and then halts. Same on every reset.

I have an AS5600 encoder fortunately, I can try that if this encoder isn’t good to go yet. I am concerned the RPM limit will be an issue but it might be ok… It worked with the Uno. I am baffled at this directory structure problem, it does not seem to have anything to do with the encoder.

Sorry, those are my own #defines for the pins. I like to have them all up top rather than scattered throughout the code.

Probably easier to just buy an FTDI adapter than trying to track down what’s causing it to crash when connected to the arduino.

For what it’s worth, mine does not need built_opt.h to use hardware serial. I think that’s only necessary for multiple serial ports at once.

And yeah, the arduino stm32 compiler is annoyingly slow. It takes forever the first time. Recompiling should be more like 30 seconds. But I think all the intermediate files get cleared if you compile a different project, so then it has to start fresh with the long compile again.

OMG guys, what’s going on here?

I fear things have become quite confused…

PA2/PA15 are the hardware serial pins of USART2 - using software serial here is not at all a good idea. Software Serial uses interrupts and will have much higher MCU overhead than hardware serial. It might work, but it’s not really recommended in combination with SimpleFOC where you want the MCU to be concentrated on motor driving, not handling software serial interrupts…

To make USART2 the default serial port, on STM32 use the build flag:

-DSERIAL_UART_INSTANCE=2

Where are you putting these build flags when using Arduino IDE, if I may ask? Arduino IDE doesn’t make it so easy to set them.

I also can’t really follow what calamity seems to have befallen your library folders, but sometimes it’s better to cut your losses, make a copy of your ino files and delete the whole Arduino environment and reinstall it. Starting with a clean slate will help get rid of problems like this…

Hey, if someone has one spare and wants to send me a Lepton I would offer to make proper board files for it, to make it easier to use…

1 Like

I would jump at the chance to trade some boards for some progress, I ordered extra boards because the marginal price of more was low, Valentine said he tested it and it seemed to work at least for him in that context, and I thought others might want them. I got 20 lepton version 2 boards, exactly a clone of the ones in the easyeda, no modifications to cause confustion. Also 20 SC60228DC encoders, Valentine recommended as compatible. If DM me your address I can put some in the mail for you asap, will give it express shipping of some kind even. Better ask for at least 2. I’ll send some magnets and a motor too if you want. And a 24 volt power supply, whatever.

This problem with the directory structure arises even with a fresh install, I tried deleting and redoing stuff. I don’t know much C to begin with, but this appears to have happened earlier on up the pipe. I think someone made a change and borked the master copy.

The angle sensor is reporting readings ok.
cpu has been set ok.

this code was enough:
#include “SoftwareSerial.h”
#include <SimpleFOCDrivers.h>
#include “encoders/sc60228/MagneticSensorSC60228.h”

// SENSOR SPI SC60228
// SPI2 PINS
#define CSN2 PA4
#define CLK2 PA5
#define MISO2 PB4
#define MOSI2 PB5

#define SS_USB_RX PA15
#define SS_USB_TX PA2
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

/** Configure the main internal regulator output voltage
*/
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);

/** Initializes the RCC Oscillators according to the specified parameters

  • in the RCC_OscInitTypeDef structure.
    */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
    RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
    RCC_OscInitStruct.PLL.PLLN = 8;
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
    RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
    RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
    Error_Handler();
    }

/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
// BAUD RATE MUST BE BETWEEN 9600…38400
// ANY OTHER BAUD RATE WILL CHOKE

SoftwareSerial SoftSerialUSB(SS_USB_RX, SS_USB_TX);
MagneticSensorSC60228 sensorSC60228(CSN2);

SPIClass SPISensor(MOSI2, MISO2, CLK2);
void setup()
{
//set pins for Software Serial communication
SoftSerialUSB.begin(38400);
pinMode(SS_USB_RX, INPUT);
pinMode(SS_USB_TX, OUTPUT);
sensorSC60228.init(&SPISensor);
delay(1000);
}

void loop()
{
SoftSerialUSB.println(“TEST SSERIAL_USB”);
SoftSerialUSB.println(F_CPU);
SoftSerialUSB.println(sensorSC60228.getAngle());

sensorSC60228.update();
delay(100);
}

I would like to try the build flags thing, I don’t know if it is necessary at this point though.

Turn off the antivirus / defender. That’s the real problem.

I sent you a DM! Don’t feel you have to do this, but if it would help you I am more than happy to spend some time on it. I think others may also benefit, as the Lepton is a very nice little driver…

I would be happy to, the progress may come too late for me, it’s not clear, but I am a believer and it’s my way of paying it forward

edit: even this doesnt work. using hte build flag appears to be counter to the way one is supposed to use arduino, as Runger said they don’t make it easy. Do I need to do that?

#include <HardwareSerial.h>

HardwareSerial mySerial1(PA15,PA2);
void setup() {

mySerial1.begin(38400);
pinMode(PB7, OUTPUT);
}

void loop() {
// put your main code here, to run repeatedly:
mySerial1.println(“test”);
delay(1000);
digitalWrite(PB7, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(PB7, LOW);
}

Yes, there are some environmental issues lurking here, as building the code is literally only a few clicks. I feel bad but this is nearly impossible for me to debug. There was another person, he ordered the Lepton and had absolutely no problem running Serial, sensors, etc. I cannot quote/disclose the name, due to privacy reasons, but he did manage everything on his own, so I’m quite certain it’s very straightforward. In addition, I’m using the exact same MCU for the mosquito board, and it works there, too.

@runger, that’s really awesome. I’m buried with multiple other projects, and now only type a few lines here, no time to even design cool new stuff. I always subscribed to the idea that I only design the hardware and others figure it out, I guess, later when I get the time, I have to change my approach and make it a lot more user-end friendly. At the end, it’s just about programming a generic g031 mcu. I guess the learning curve may be steeper than I estimated for new people coming into the field and I took too many things for granted.

Cheers,
Valentine

PS here is another full-stack design (the whole servo mechanics are also my design) I did for a dual-motor ultra-high torque robotic servo based on the Lepton (only re-arranged the components to fit the servo inside) and it works, so there are so many things you could do with that design. I’m quite certain it works, so @Anthony_Douglas don’t give up, it will eventually come together.

1 Like

I deleted the library and reinstalled… same deal. Well the SPI port works ok, just not the UART. Perhaps I can debug and get things approximately working using software serial and then take that out later. I could use pulsin() and the pwm peripheral on the pico to control the board perhaps. I can only access like 4 pins, it’s so tiny I have to use whatever is broken out to the picoblade connectors.

Valentine: how did you get the serial port working, exactly? The build_opt thing doesn’t work in arduino, so it must have been some other way? Were you using STMcubeIDE? As you say it worked for you, an advisable approach is to use exactly the same approach as you and then diversify or build upon that. That’s why I asked for an exact .ino file a couple days ago, the exact stuff that is known to work. Although agreed it’s not exactly the same stuff i.e. the voltage was not suitable for my motor. But we need a standard test file. The commander thing that is available for the uno is good.

c:/users/anthony/appdata/local/arduino15/packages/stmicroelectronics/tools/xpack-arm-none-eabi-gcc/10.3.1-2.3/bin/…/lib/gcc/arm-none-eabi/10.3.1/…/…/…/…/arm-none-eabi/bin/ld.exe: C:\Users\anthony\AppData\Local\Temp\arduino-sketch-E6525D67E19444744D397AC9C0CF5638/sketch_feb14combiningoldarduinowith new stm32stuff.ino.elf section .text' will not fit in region FLASH’
c:/users/anthony/appdata/local/arduino15/packages/stmicroelectronics/tools/xpack-arm-none-eabi-gcc/10.3.1-2.3/bin/…/lib/gcc/arm-none-eabi/10.3.1/…/…/…/…/arm-none-eabi/bin/ld.exe: region `FLASH’ overflowed by 13180 bytes
collect2.exe: error: ld returned 1 exit status

exit status 1

Compilation error: exit status 1

Sounds like there isn’t enough flash on this microcontroller??

Code I was trying to compile:>

#include “SoftwareSerial.h”
#include <SimpleFOCDrivers.h>
#include “encoders/sc60228/MagneticSensorSC60228.h”
#include <SimpleFOC.h>
// SENSOR SPI SC60228
// SPI2 PINS
#define CSN2 PA4
#define CLK2 PA5
#define MISO2 PB4
#define MOSI2 PB5

#define SS_USB_RX PA15
#define SS_USB_TX PA2
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

/** Configure the main internal regulator output voltage
*/
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);

/** Initializes the RCC Oscillators according to the specified parameters

  • in the RCC_OscInitTypeDef structure.
    */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
    RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
    RCC_OscInitStruct.PLL.PLLN = 8;
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
    RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
    RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
    Error_Handler();
    }

/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
// BAUD RATE MUST BE BETWEEN 9600…38400
// ANY OTHER BAUD RATE WILL CHOKE

SoftwareSerial SoftSerialUSB(SS_USB_RX, SS_USB_TX);
MagneticSensorSC60228 sensor(CSN2);
BLDCMotor motor = BLDCMotor(7);
BLDCDriver6PWM driver = BLDCDriver6PWM(PA8, PA7, PB3, PB0, PB6, PB1);
SPIClass SPISensor(MOSI2, MISO2, CLK2);
Commander command = Commander(SoftSerialUSB);
void onMotor(char* cmd){ command.motor(&motor, cmd); }

void setup()
{
//set pins for Software Serial communication
SoftSerialUSB.begin(38400);
pinMode(SS_USB_RX, INPUT);
pinMode(SS_USB_TX, OUTPUT);
SoftSerialUSB.println(“got this far, testing serial port”);
SoftSerialUSB.println(F_CPU);
sensor.init(&SPISensor);
delay(1000);
motor.linkSensor(&sensor);
driver.voltage_power_supply = 24;
driver.init();
motor.linkDriver(&driver);
motor.controller = MotionControlType::torque;
motor.voltage_limit = 12;
motor.useMonitoring(SoftSerialUSB);
// initialise motor
motor.init();
// align encoder and start FOC
motor.initFOC();
// set the inital target value
motor.target = 2;
// define the motor id
command.add(‘A’, onMotor, “motor”);
SoftSerialUSB.println(F(“Motor commands sketch | Initial motion control > torque/voltage : target 2V.”));
delay(1000);

}

void loop()
{
motor.loopFOC();

// iterative function setting the outter loop target
// velocity, position or voltage
// if tatget not set in parameter uses motor.target variable
motor.move();

// user communication
command.run();
//SoftSerialUSB.println(sensor.getAngle());
//sensorSC60228.update();
}

It’s a combo of what worked on the arduino uno with the adaptations for the STM32 of concern and this exact encoder.

update: beware when cutting and pasting code, sometimes quotes get replaced with characters that cause problems with the compiler. There should be a thing to enclose code. I don’t know how Deku did it, there is nothing on the toolbar when editing/making a post.

Update: was not able to get the build option stuff working, despite finding some instructions on how to modify the boards.txt file in order to add build options to the compiler. I tried adding the one Runger mentioned but it didn’t seem to make any differnce, tried a couple more things, didn’t work, put it back.

this code does something, it starts the motor initialization and runs the pole pair check ,but the results are borked. At least it doesn’t run out of flash memory.

recalling what was said about Valentine encountering problemw with this encoder driver not working yet with other modules of the system, I plan to try switching to an as5600 encoder and seeing if I can get that to do something useful . That’s what worked with the arduino uno.

#include "SoftwareSerial.h"
#include <SimpleFOCDrivers.h>
#include "encoders/sc60228/MagneticSensorSC60228.h"
#include <SimpleFOC.h>
// SENSOR SPI SC60228
// SPI2 PINS
#define CSN2 PA4
#define CLK2 PA5
#define MISO2 PB4
#define MOSI2 PB5

#define SS_USB_RX  PA15
#define SS_USB_TX  PA2
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
  RCC_OscInitStruct.PLL.PLLN = 8;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}
// BAUD RATE MUST BE BETWEEN 9600..38400
// ANY OTHER BAUD RATE WILL CHOKE

SoftwareSerial SoftSerialUSB(SS_USB_RX, SS_USB_TX);
MagneticSensorSC60228 sensor(CSN2);
BLDCMotor motor = BLDCMotor(7);
BLDCDriver6PWM driver = BLDCDriver6PWM(PA8, PA7, PB3, PB0, PB6, PB1);
SPIClass SPISensor(MOSI2, MISO2, CLK2);

void setup()
{
  //set pins for Software Serial communication
  SoftSerialUSB.begin(38400);
  pinMode(SS_USB_RX, INPUT);
  pinMode(SS_USB_TX, OUTPUT);
  SoftSerialUSB.println("got this far, testing serial port");
  SoftSerialUSB.println(F_CPU);
sensor.init(&SPISensor);
  delay(1000);
motor.linkSensor(&sensor);
 driver.voltage_power_supply = 24;
  driver.init();  
   motor.linkDriver(&driver);
    motor.controller = MotionControlType::torque;
     motor.voltage_limit = 12;
  motor.useMonitoring(SoftSerialUSB);
    // initialise motor
  motor.init();
  // align encoder and start FOC
  motor.initFOC();
    // set the inital target value
  motor.target = 2;
   // define the motor id


 delay(1000);

}

void loop()
{
  motor.loopFOC();

  // iterative function setting the outter loop target
  // velocity, position or voltage
  // if tatget not set in parameter uses motor.target variable
  motor.move();
  SoftSerialUSB.println("still running");
delay(100);
  //SoftSerialUSB.println(sensor.getAngle());
  //sensorSC60228.update();
}

serial output from the code above was:
64000000

MOT: Monitor enabled!

MOT: Init

MOT: Enable driver.

MOT: Align sensor.

MOT: sensor_direction==CW

MOT: PP check: fail - estimated pp: 4095.99

MOT: Zero elec. angle: 2.33

MOT: No current sense.

MOT: Ready.

still running

If I get the time I can try, but it may take a day or two or more. I’m away on a trip and will be back Friday.

It’s the 6th icon from the left above the text area. Looks like </> and the tooltip says “Preformatted text (Ctrl+E)”.

Lepton does not have enough flash for Commander. I wrote a quick and dirty serial communication interface via the Arduino IDE serial monitor, where you type single letter commands to read and write variables for tuning and debugging. Lowercase to output the current value, uppercase followed by a number to set the value and then print it for confirmation. Feel free to change the letters to whatever you prefer, or just use it as inspiration to make something better.

void SerialComm()
{
  switch(Serial.read())
  {
  case '?':
    Serial.print("sensor_direction ");
    Serial.print(motor.sensor_direction);
    Serial.print(", zero_electric_angle ");
    Serial.println(motor.zero_electric_angle);
    break;
  case 's': Serial.print("shaft_velocity "); Serial.println(motor.shaft_velocity); break;
  case 'a':
    Serial.print("shaft_angle ");
    Serial.print(motor.shaft_angle);
    Serial.print(", electric_rotations ");
    Serial.print(sensor.electric_rotations);
    Serial.print(", electric_sector ");
    Serial.println(sensor.electric_sector);
    break;
  case 'K': motor.KV_rating = Serial.parseFloat(); Serial.print("Set ");
  case 'k': Serial.print("kv "); Serial.println(motor.KV_rating); break;
  case 'R': motor.phase_resistance = Serial.parseFloat(); Serial.print("Set ");
  case 'r': Serial.print("phase_resistance "); Serial.println(motor.phase_resistance); break;
  case 'T': target_range = Serial.parseFloat(); Serial.print("Set ");
  case 't': Serial.print("target_range "); Serial.println(target_range); break;

  case 'V': motor.voltage_limit = Serial.parseFloat(); Serial.print("Set ");
  case 'v': Serial.print("motor.voltage_limit "); Serial.println(motor.voltage_limit); break;
  case 'C': motor.current_limit = motor.PID_velocity.limit = Serial.parseFloat(); Serial.print("Set ");
  case 'c': Serial.print("motor.current_limit "); Serial.println(motor.current_limit); break;

  case 'O': motor.PID_velocity.output_ramp = Serial.parseFloat(); Serial.print("Set ");
  case 'o': Serial.print("motor.PID_velocity.output_ramp "); Serial.println(motor.PID_velocity.output_ramp); break;
  case 'F': motor.LPF_velocity.Tf = Serial.parseFloat(); Serial.print("Set ");
  case 'f': Serial.print("motor.LPF_velocity.Tf "); Serial.println(motor.LPF_velocity.Tf); break;
  case 'P': motor.PID_velocity.P = Serial.parseFloat(); Serial.print("Set ");
  case 'p': Serial.print("motor.PID_velocity.P "); Serial.println(motor.PID_velocity.P); break;
  case 'I': motor.PID_velocity.I = Serial.parseFloat(); Serial.print("Set ");
  case 'i': Serial.print("motor.PID_velocity.I "); Serial.println(motor.PID_velocity.I); break;
  case 'D': motor.PID_velocity.D = Serial.parseFloat(); Serial.print("Set ");
  case 'd': Serial.print("motor.PID_velocity.D "); Serial.println(motor.PID_velocity.D); break;

  case 'W': motor.P_angle.P = Serial.parseFloat(); Serial.print("Set ");
  case 'w': Serial.print("motor.P_angle.P "); Serial.println(motor.P_angle.P); break;
  }
}
1 Like

Thanks man, I will check it out. Even when I remove the commander entirely, it still often runs out of flash. It’s clear this MCU is way too small, even the most elementary sketches are too big. This for instance is 688 bytes too big according to the compiler:

#include <SimpleFOC.h>
#include "SoftwareSerial.h"
#include <Wire.h>
#define SS_USB_RX  PA15
#define SS_USB_TX  PA2
// magnetic sensor instance
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
  RCC_OscInitStruct.PLL.PLLN = 8;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

MagneticSensorI2C sensor = MagneticSensorI2C(0x36, 12, 0X0C, 4);
// BLDC motor & driver instance
BLDCMotor motor = BLDCMotor(7);
BLDCDriver6PWM driver = BLDCDriver6PWM(PA8, PA7, PB3, PB0, PB6, PB1);
SoftwareSerial SoftSerialUSB(SS_USB_RX, SS_USB_TX);
// commander interface
void setup() {
Wire.setSDA(PB7); 
Wire.setSCL(PB8);
Wire.begin();
  
  SoftSerialUSB.begin(38400);
  SoftSerialUSB.println("serial test");
  // initialise magnetic sensor hardware
  sensor.init();
  // link the motor to the sensor
  motor.linkSensor(&sensor);

  // driver config
  // power supply voltage [V]
  driver.voltage_power_supply = 24;
  driver.init();
  // link driver
  motor.linkDriver(&driver);

  // set control loop type to be used
  motor.controller = MotionControlType::torque;

  // contoller configuration based on the control type 
  motor.PID_velocity.P = 0.2;
  motor.PID_velocity.I = 20;
  motor.PID_velocity.D = 0;
  // default voltage_power_supply
  motor.voltage_limit = 12;

  // velocity low pass filtering time constant
  motor.LPF_velocity.Tf = 0.01;

  // angle loop controller
  motor.P_angle.P = 20;
  // angle loop velocity limit
  motor.velocity_limit = 50;


  // comment out if not needed
  motor.useMonitoring( SoftSerialUSB);

  // initialise motor
  motor.init();
  // align encoder and start FOC
  motor.initFOC();

  // set the inital target value
  motor.target = 3;

  // Run user commands to configure and the motor (find the full command list in docs.simplefoc.com)
 SoftSerialUSB.println("got this far");
  
  _delay(1000);
}


void loop() {

  motor.loopFOC();

  // iterative function setting the outter loop target
  // velocity, position or voltage
  // if tatget not set in parameter uses motor.target variable
  motor.move();

}

I’m going to have to remove the softwareserial stuff, which means I’m totally flying blind. I’m using the I2C now so I don’t even have that pin, maybe I can use the old pins from the SPI port.

It does not need the pid loop tuning stuff but I left it in as I wanted to change the bare minimum to adapt it from the uno, which it worked on, to the stm32