Edgar Huckert 08-2019

Controlling a brushless motor with LPC1768 and HC-12

This time I used an NXP LPC1768 microcontroller to generate the PWM signal for the ESC controlling the brushless motor. After having played around with different Arduino versions (Duemillanove, Nano, DUE) and after having experienced failures due to different PWM basic speeds I found that using an LPC1768 was the simplest solution. The MBED library offers an uncomplicated set of functions for PWM. It also offers the concept of callback routines for simple reception of serial bytes (this is a simplified version of the "interrupt service routines" known found in real time systems). BTW: I use here a global variable rxVal set in the callback routine and read in the main() routine. In more complicated programs a lock mechanism (mutex etc.) may be necessary to avoid simultaneous access to the shared variable.

The receiver is mainly the LPC1768 microcontroller and a HC-12 433 Mhz module acting as receiver. No Arduino is needed here: the LPC1768 does the complete job including the production of the PWM signal. The ESC and the motor are - strictly spoken - not part of the the receiver.

As sender I use here and Arduino Nano connected to a second HC-12 module. This module receives simple control bytes in the range '0' - '9'. These control bytes are translated to PWM duty cycle values (range 0.0 to 1.0) via a simple table. I enter the control bytes via TeraTerm (under Windows) or minicom (under Linux). It is clear that this can be replaced by a potentiometer (variable resistance) connected to an analogue input pin on an Arduino that transmits these (translated) values to a HC-12 module.

The parts and components I used are the following:

Here is a diagram showing this configuration:

PWM433MhzLPC1768  

Here is the C code for the NXP LPC1768. The code must be compiled and loaded with the MBED compiler:

// module PWM433Mhz
// Dr.Edgar Huckert 08-2019
// V2.1 - is OK
//
// Uses a HC-2 433Mhz module to receive bytes (9600 Baud)
// Uses PWM(500 Hz) to control an ESC for a brushless motor 
// The ESC is: Robbe 
// The brushless motor is: Simprop Magic Torque
//
// on the other side (remote control sender):
// HC-12 module used in TX direction (RX pin connected to Arduino TX)
// Arduino Nano used as USB-Serial (5V) converter
// On PC/Laptop (Windows): TeraTerm with pseudo serial(USB) port
//
#include "mbed.h"
//
DigitalOut myled(LED1);
PwmOut PWM1(p23);
Serial ser(p28, p27); // RX from HC-12 on pin 27
float rxVal = 0.5;
float rxValTable[10] =
{
    0.0, 0.50, 0.55, 0.60, 0.65,
    0.70, 0.75, 0.80, 0.85, 0.90
};

// ----------------------------------------------
// the callback routine: receives bytes from the HC-12 module
// Received bytes in range '0' - '9'
// Sets the global variable rxVal
void gotBytes()
{
    char ch = ser.getc();
    // normalize the received char (byte) to the range '0 - '9'
    ch = ch & 0x7f;
    printf("ori %c", ch);
    if (ch <= ' ') ch = '0';
    if (ch < '0')  ch = '0';
    if (ch > '9')  ch = '9';
    rxVal = rxValTable[ch - '0'];
    printf(" %c", ch);
    printf(" rxVal=%f\r\n", rxVal);
    return;
}   // end gotBytes()
    
// ---------------------------------------
void initMotor()
{
    // configure the serial interface connected to a HC-12 module (433MHz)
    printf("configure ser.interf. for HC-12\r\n");
    // register the call back routine
    ser.attach(& gotBytes);
    ser.baud(9600);
    ser.format(8, SerialBase::None, 1);
    //
    // start PWM on pin 23
    printf("initMotor()\r\n");
    PWM1.period(0.002); // set PWM period to 2 ms=500 Hz
    PWM1 = 0.5;         // duty cycle 50%
    for (int n=0; n < 5; n++)
    {
        myled = 1;
        wait(0.2);
        myled = 0;
        wait(0.2);
    }
    printf("initMotor() OK\r\n");
}   // end initMotor()

// ----------------------------------------
// S1ets a new PWM duty value
// parameter val: the new duty cycle
void driveMotor(float val)
{
    printf("duty cycle=%f\r\n", val);
    // set the duty cycle value 
    PWM1 = val;         // set duty cycle 
}   // end driveMotor()

// ----------------------------------------
int main() 
{
    float oldRxVal = rxVal;
    unsigned count = 0;
    //
    printf("PWM433Mhz starting...\r\n");
    //
    initMotor();
    //
    // Note: the control bytes varying the PWM ducty cycle
    //       are received in callback routine gotBytes()
    while (1)
    {
      if (rxVal != oldRxVal)
        driveMotor(rxVal);
      oldRxVal = rxVal;
      wait(0.333);
      count++;
      if ((count % 100) == 0)
        printf("alive\r\n");
    }
}   // end main()

The Arduino sketch code for the simple 433Mhz sender is here. Essentially this code and the related hardware are a simple USB to serial converter. Using an Arduino here avoids using a RS232-to-5Vserial converter (MAX...chip). It also facilitates life if your laptop or PC no longer has a serial RS232 interface:

const int ledPin = 13;
unsigned  ledVal = 0;
unsigned  count  = 0;
char      ch     = 0;

// -------------------------------------------
void setup()
{
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, ledVal);
}   // end setup()

// --------------------------------------------
void loop()
{
  if (Serial.available() > 0)
  {
    // read from the Arduino RX pin connected to 
    // PC/USB (TX pin)
    ch = Serial.read();
    // Send  the received char via TX pin 
    // This TX pin on the Arduino is connected
    // to RX on the HC-12
    Serial.print(ch);
    count++;
    // blink the LED
    ledVal =  ! ledVal;
    digitalWrite(ledPin, ledVal);
  }
  else
  {
    delay(1);  // wait 1 ms
  }
}   // end loop()

Contact

If you want to contact me: this is my
mail address

Remarks:

This is version 2 of my WEB pages.
Copyright for all images, texts and software on my pages: Dr. E. Huckert