Trouble interfacing with LPC1768 with custom pin definitions

Hello,

I thought it could be frequencies as well, so I left this script running for 10 minutes:

#include "mbed.h"

//Stepper motor movement script, commenting this out while testing sd card functionality

//DigitalOut xEN(P2_1); //Pin ??(74) of LPC
DigitalOut xSTP(P2_2); //Pin ??(73) of LPC
DigitalOut xDIR(P2_6); //Pin ??(67) of LPC


//DigitalOut ySTP(P0_19); //Pin 59
//DigitalOut yDIR(P0_20); //Pin 58



void spinattempt(double sleeptime)
{
   for(int i = 0; i < 100; i++){
    xSTP = 1;
    thread_sleep_for(sleeptime);
    xSTP = 0;
    thread_sleep_for(sleeptime);

   }
   spinattempt(sleeptime + 0.001); 
}
int main() {

    xDIR = 0; //Sets dir pin to high and direction to clockwise
    xSTP = 0;
    //xSTP = 1;
    double sleeptimedur = 0.002;
   //Should keep spinning till I unplug the SKR V1.3
    spinattempt(sleeptimedur);

}

but the x stepper did nothing. It worked in marlin with pronter fance though with the marlin firmware. Is there something marlin is doing that im not?

thread_sleep_for() is defined as:

void thread_sleep_for(uint32_t millisec)

So passing a double 0.002 will result in a call with sleeptime = 0. And adding 0.001 will still leave it 0. The compiler should have warned you about the implicit type conversion and loss of accuracy.
The stepper needs pulslength > 1,9 µs, it will do nothing when pulses are shorter.

Mbed6 uses std::chrono to avoid such mistakes, there you can write:

ThisThread::sleep_for(2ms);
ThisThread::sleep_for(2s);

I’ve quite a bit of time trying to get “ThisThread” to work, but im always getting something along the lines of:

src/main.cpp:30:18: error: ‘std::chrono::this_thread’ has not been declared

Im using platformio on ubuntu 20.04 to compile:

#include "mbed.h"
#include <chrono>
#include "mbed_events.h" 

//Stepper motor movement script, commenting this out while testing sd card functionality

//DigitalOut xEN(P2_1); //Pin ??(74) of LPC
DigitalOut xSTP(P2_2); //Pin ??(73) of LPC
DigitalOut xDIR(P2_6); //Pin ??(67) of LPC


//DigitalOut ySTP(P0_19); //Pin 59
//DigitalOut yDIR(P0_20); //Pin 58



void spinattempt(double sleeptime)
{
   for(int i = 0; i < 100; i++){
    xSTP = 1;
    //thread_sleep_for(sleeptime);
    xSTP = 0;
    //thread_sleep_for(sleeptime);

   }
   spinattempt(sleeptime + 0.001); 
}
int main() {
    
    std::chrono::this_thread::sleep_for(2ms);


    xDIR = 0; //Sets dir pin to high and direction to clockwise
    xSTP = 0;
    //xSTP = 1;
    double sleeptimedur = 0.002;
   //Should keep spinning till I unplug the SKR V1.3
    //spinattempt(sleeptimedur);
}

ok, I think PIO is using some 5.x version.
Then it shoud work with `ThisThread::sleep_for(2);
Anyway, the argument is an integer and in milliseconds.

src/main.cpp:30:5: error: ‘this_thread’ has not been declared

Do you have a full example of this_thread working? chrono, thread, and std are saying they don’t define this and trying to add build flags in the “build_fags =” section for cmake and g++ like the posts linking eachother on here describe, don’t seem to do anything

in mbed 5.15 the chrono is not implemented, so just use ThisThread::sleep_for() or thread_sleep_for(). The later does the same and is included for C compatibility.
https://os.mbed.com/docs/mbed-os/v5.15/mbed-os-api-doxy/namespacertos_1_1_this_thread.html#a770153ce44f174497a5c526e81b8fbb5

this does not apply to mbed-os:

#include<thread>

Thats what i’ve been doing. I tried replacing the double with int so that I have this:

#include "mbed.h"

//Stepper motor movement script, commenting this out while testing sd card functionality

//DigitalOut xEN(P2_1); //Pin ??(74) of LPC
DigitalOut xSTP(P2_2); //Pin ??(73) of LPC
DigitalOut xDIR(P2_6); //Pin ??(67) of LPC


//DigitalOut ySTP(P0_19); //Pin 59
//DigitalOut yDIR(P0_20); //Pin 58



void spinattempt(int sleeptime)
{
   for(int i = 0; i < 100; i++){
    xSTP = 1;
    thread_sleep_for(sleeptime);
    xSTP = 0;
    thread_sleep_for(sleeptime);

   }
   spinattempt(sleeptime + 0.001); 
}
int main() {

    xDIR = 0; //Sets dir pin to high and direction to clockwise
    xSTP = 0;
    //xSTP = 1;
   int sleeptimedur = 0.002;
   //Should keep spinning till I unplug the SKR V1.3
    spinattempt(sleeptimedur);

and it does nothing, I’ve replaced 0.002 with 1 and it also doesn’t work.

In this last iteration of the code you’re assigning a float (0.002) to an int (sleeptimedur).

I believe the value of sleeptimedur will = 0 in the call to spinattempt(…).

Not sure what this line in spinattempt(…) is supposed to do:

spinattempt(sleeptime + 0.001); 
  1. The increment will not proceed as expected because again assigning a float to an integer
  2. The increment is done then the function exits. Next time it’s called ‘sleeptime’ will be assigned with the called value.

Note also your code comment about “keep spinning until I unplug the SKR V1.3” is also a misconception.

The function spinattempt(…) will be called once (looping through 100 cycles of IO pins on & off) then return to main() which then terminates. You need to put spinattempt(…) in a forever loop if you want it to continue indefinitely (unlike arduino).

The following compiles (using Mbed Studio) and runs as expected (I substituted LEDs on my LPC4088QSB for your I/O pins).

#include "mbed.h"

//DigitalOut xEN(P2_1); //Pin ??(74) of LPC
//DigitalOut xSTP(P2_2); //Pin ??(73) of LPC
//DigitalOut xDIR(P2_6); //Pin ??(67) of LPC
DigitalOut xSTP(LED1); //Pin ??(73) of LPC
DigitalOut xDIR(LED2); //Pin ??(67) of LPC

void spinattempt(int sleeptime)
{
    for(int i = 0; i < 100; i++){
        xSTP = 1;
        thread_sleep_for(sleeptime);
        xSTP = 0;
        thread_sleep_for(sleeptime);
    }
}

int main() {
    xDIR = 0; //Sets dir pin to high and direction to clockwise
    xSTP = 0;
    //xSTP = 1;
    int sleeptimedur = 2;
    //Should keep spinning till I unplug the SKR V1.3
    while(1) {
        spinattempt(sleeptimedur);
        thread_sleep_for(1000);
    }
}

The above code should toggle the I/O at 250Hz for 100 x 2 x 2 = 400ms, wait 1 sec then repeat indefinitely.

Edit: Oh, forgot to mention this is using Mbed OS 5.15

And how is the code transferred to the board? When the SD card bootloader is used, then the application start has to be added to the mbed_app.json.

I transfer the code via SD card to the board.

Do you know a good resource for how to put together a valid mbed_app.json? My project doesn’t have one of those and im not sure how to configure those.

Also, I don’t think the firmware is being read from the sd card, the board already has the smoothieboard bootloader on it, but when I attempt to create a test file, it doesn’t show up on the sd card:

int main() {
//Create file as sanity check to confirm program is being read by the board
ofstream MyFile(“filename.txt”);
MyFile << “If this reads, then I think the board flash the firmware”;
MyFile.close();

}

I haven’t used the bootloader stuff before, and you need to know about the bootloadersize and what start address it will call. The smoothieware bootloader seems to consume the first 16 k of the flash, then the mbed_app.json may look like this:

{
    "target_overrides": {
        "*": {
                 "target.mbed_app_start": "0x4000",
                 "target.mbed_app_size": "0x7C000"
        }
    }
}

target.mbed_app_size may be omitted, I’m not sure. And this is documented for Mbed 6.x, I’m also not sure if this does work for older Mbed 5.x versions that PIO is still using.
When you have a debug probe to program the board, then you could overwrite the bootloader and run without the mbed_app settings. But then you should be sure how to restore the bootloader if needed.

And you cannot simply use ofstream, thats for programs running on a pc. The filesystem must be declared for this to work and cpp streams are not optimized for embedded systems and consume a lot of resources…

Ok so I think im getting closer to getting this working.

I used your above mbed_app.json file with removing mbed_app_size and keeping it in the code, and with the mbed_app.json, my switch power supply is reading 0.45mA instead of 0.22 mA.

Normally when I think its in the boot phase, it starts off at around 50mA then falls to 0.22mA but now it starts at about 50mA then it steadily stays within 45mA. It seems to be doing something now, just not quite spinning the steppers yet.

Can you install mbed-cli for compiling? Or have you used the online Compiler before?

mbed-cli has compatability with ubuntu so I can install it and no i’ve not used the online compiler before. Will compiling with mbed-cli/online compiler do something different?

Not very different, but you could use more recent Mbed versions.

Ok, if your code is executing now, make sure xEN=0 is in and sleep_for(2) is used.

This should work:


#include "mbed.h"


//Stepper motor movement script, commenting this out while testing sd card functionality

DigitalOut xEN(P2_1); //Pin ??(74) of LPC
DigitalOut xSTP(P2_2); //Pin ??(73) of LPC
DigitalOut xDIR(P2_6); //Pin ??(67) of LPC


//DigitalOut ySTP(P0_19); //Pin 59
//DigitalOut yDIR(P0_20); //Pin 58


int main() {
    xEN = 0;
    
    while(1) {
        xDIR = 1;
        for (int i = 0; i<200*16; i++) {
            xSTP = 1;
            ThisThread::sleep_for(1);
            xSTP = 0;
            ThisThread::sleep_for(1);
        }

        xDIR = 0;
        for (int i = 0; i<200*16; i++) {
            xSTP = 1;
            ThisThread::sleep_for(1);
            xSTP = 0;
            ThisThread::sleep_for(1);
        }
    }
}

IT WORKS, I initialized the xEN pin and the stepper turned on! I’ll mark the question with the mbed_app.json as correct! just remove “target.mbed_app_size”. Why did adding that fix the json file fix it though?

The ‚problem‘ is the bootloader. This is located in the flash and started after reset. When the bootloader does not find anything to load, control is passed to the application. But the application is located by default also at the reset vector. When it should work with the bootloader, it must be compiled and linked to start at the address where the bootloader it will start. And this magic is performed by the mbed_app_start setting, it is passed to the linker script and the code will be relocated to the given address.

Anyway, I recommend to use a debug probe for more frequent programming, it’s much more fun than always swapping the SD card.