DIY Arduino based RC transmitter

 

Arduino-RC-Controller-with-14-channels-and-MPU6050-Accelerometer-and-Gyro-600

Dejan over at HowToMechatronics posted a detailed how-to on building DIY Arduino RC transmitter:

Now I can wirelessly control any Arduino project with just some small adjustments at the receiver side. This transmitter can be also used as any commercial RC transmitter for controlling RC toys, cars, drones and so on. For that purpose it just needs a simple Arduino receiver which then generates the appropriate signals for controlling those commercial RC devices. I will explain how everything works in this video through few examples of controlling an Arduino robot car, controlling the Arduino Ant Robot from my previous video and controlling a brushless DC motor using an ESC and some servo motors.

More details on HowToMechatronics’ project page.

Check out the video after the break.

ESP32 (38) – Factory reset

In the previous two posts of this tutorial, I explained how to perform an over-the-air update of the firmware running on the esp32 chip.

Sometimes you may need to revert to the factory firmware, that is the firmware stored in the flash memory when the chip was programmed. Many consumer devices have a button or a pin that, if you press it for some seconds, triggers a reset function:

A10317_image1

In this post I’ll show you how to add this functionality to your project.

Partitions

As explained in a previous post, the flash memory connected to the esp32 chip is divided into some partitions, based on a layout configured when you program the chip.

Partitions that can store firmwares are of the app type. The partition that contains the firmware programmed via USB, has the factory subtype.

The esp-idf framework includes a method to search partitions in the flash memory:

#include "esp_partition.h"
[...]
esp_partition_iterator_t esp_partition_find(
  esp_partition_type_t type, esp_partition_subtype_t subtype, const char* label);

You can specify some filters to narrow down the results (they are not mandatory, use NULL if a filter is not needed): the type of the partition, the subtype and also a specific label.

If you want to look for the partition that contains the factory firmware, you can therefore write:

esp_partition_iterator_t pi = esp_partition_find(
  ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL);

The method returns a partition iterator, that is an object that allows to scroll through the partitions found.

If the search was successful, this object is not NULL and you can get a pointer to the partition with the method:

const esp_partition_t* esp_partition_get(esp_partition_iterator_t iterator);

After the use, it’s important to release the iterator object with:

void esp_partition_iterator_release(esp_partition_iterator_t iterator);

After having obtained the correct partition, that contains the factory firmware, you only have to flag it as the boot partition and restart the chip:

if(pi != NULL) {
  const esp_partition_t* factory = esp_partition_get(pi);
  esp_partition_iterator_release(pi);
  if(esp_ota_set_boot_partition(factory) == ESP_OK) esp_restart();	
}

Demo

In the following video you can see how to perform a factory reset. In the video you can also learn how to “count” the number of seconds a button is pressed to trigger the reset function only after a fixed threshold (3 seconds in my example). Enjoy!

Regaining debug access of NXP i.MX RT1064-EVK executing WFI

i.MX-RT1064-EVK-Boar

Erich Styger writes:

Working with low power modes can be challenging. It can severely affect debugging capabilities of a microprocessor or microcontroller. I ported a FreeRTOS application using the Tickless Idle Mode to the NXP i.MX RT1064 board, and all of a sudden, the board was unresponsive to any debugger connection. Luckily the board was not really bricked, but it took me while to find a way to recover it. So for when you end up in a situation with a ‘bricked’ i.MX RT1064 board, this article might be helpful for you to recover it.

More details on MCU on Eclipse blog.

DCC, configure the decoder with CVs

In my previous tutorial I explained how to build a simple DCC accessory decoder with Arduino.

To keep the sketch simple, all the configuration parameters for the decoder (in particular its address) were defined as constants:

dcc-cv-001Often it can be useful to change the configuration of the decoder without re-programming its firmware (= the sketch that runs on the ATMega microcontroller). The DCC standard includes a document (S-9.2.2 DCC Configuration Variables) that introduces – for the decoders – the idea of Configuration Variables (CV).

CVs are parameters, stored in a non-volatile way (it means that the values are kept also when the power is off) in the decoders, which can define the behavior of the decoder itself.

NMRA defines, in the same S-9.2.2 document, a list of CVs – numbered from 1 to 1024 – and a meaning for each of them. For example, for an accessory decoder it is established that its address (9 bits) is contained in CV513 and 521:

dcc-cv-002

When you buy a commercial decoder, in the manual it is always given a table that indicates, for each supported CV, the meaning. For example, the manual of the ESU SwitchPilot Servo decoder, a decoder able to command servos to activate turnouts or other movements, lists the CVs that control position and speed of the 4 servos:

dcc-cv-003

Many digital stations support the service mode (document S-9.2.3), that is, they are able to program the values of the CVs of a decoder connected to a particular output, called the programming track. The model maker can therefore adjust the behavior of the decoders installed in the locomotives or that control accessories simply positioning the locomotives (or connecting the accessory decoders) on the programming track and programming the correct values in the CVs.

CV1 vs CV513

The NMRA standard provides that the CVs that can be used by accessory decoders are those from 513 to 1024. In fact, many manufacturers, in order not to create confusion or differences between the different types of decoders, have decided to use “low” CV numbers for accessory decoders. This is the reason why many accessory decoders use CVs 1 and 9 to configure their address.

NmraDcc

Once you have learned the meaning of the CVs, let’s see how to manage their programming in our sketch.

We have to store the CV values in a memory that is not erased every time we turn off the decoder. The ATMega328 processor used by the Arduino Uno has a non-volatile memory of 1024 bytes and, thanks to the Arduino’s EEPROM library, we can store and read values from this memory.

The NmraDcc library can independently manage the CVs or – alternatively – leave it completely to the external program.

For example, in the case of writing a CV (the command station that writes the value of a CV in the decoder), the NmraDcc library offers two callback functions:

  • extern uint8_t notifyCVWrite( uint16_t CV, uint8_t Value);
  • extern void notifyCVChange( uint16_t CV, uint8_t Value);

The first substitutes the standard CV handling of the library, while the second one is called to notify that a CV changed its value. If you inspect the source code of the library, the difference is clear:

dcc-cv-004

The library also defines the numbers of some standard CVs, including those related to the decoder address:

dcc-cv-005

LED decoder

Let’s go back to the sketch of the LED decoder of the previous tutorial and add the CV management.

Define two CVs:

  • the working mode (CV10)
  • the blink frequency (CV11)

Thanks to CV10 it will be possible to choose whether the activated LED will be stready on (CV value = 0) or blinking (CV value = 1). In this second case, the blink frequency will be configured via the CV11 (from value 1 = 5 seconds to value 100 = 50ms).

First, let’s define a constant for each CV and its number:

#define CV_ACCESSORY_DECODER_MODE        10
#define CV_ACCESSORY_DECODER_BLINK_FREQ  11

You also need some variables that will contain the runtime value for those CVs to avoid continuously reading the EEPROM (which, according to the datasheet, has a life cycle of about 100,000 reads/writes):

int decoderMode;
int blinkFrequency;

In the setup() method, you have to read the values of the CVs from the EEPROM and store them in the variables:

decoderMode = Dcc.getCV(CV_ACCESSORY_DECODER_MODE);
blinkFrequency = Dcc.getCV(CV_ACCESSORY_DECODER_BLINK_FREQ);

Let the library handle the CVs. To be informed about when a value changes and update the variables accordingly, implement the notifyCVChange() method:

void notifyCVChange(uint16_t CV, uint8_t Value) {
 
  if(CV == CV_ACCESSORY_DECODER_MODE) decoderMode = Value;
  else if(CV == CV_ACCESSORY_DECODER_BLINK_FREQ) blinkFrequency = Value;
}

Blink

To make the led blink, you can use the Timer1 library which allows to trigger a callback function periodically:

This callback function simply changes the led status:

void blinkLED() {
  digitalWrite(ledActive, !digitalRead(ledActive));
}

If the decoder is in blink mode, when the output status is changed, the active led is identified and the callback function is scheduled according to the frequency configured in the appropriate CV. Otherwise the led is simply switched on:

if(outputInPair == 0) {      
  digitalWrite(GREEN_LED_PIN, LOW);
  ledActive = RED_LED_PIN;
} else {
  digitalWrite(RED_LED_PIN, LOW);
  ledActive = GREEN_LED_PIN;    
}
if(decoderMode == 1) {
  Timer1.setPeriod(5000000 / blinkFrequency);
  Timer1.attachInterrupt(blinkLED);
} 
else digitalWrite(ledActive, HIGH);
}

lettura CV

The DCC standard also includes the possibility – for a command station – to read the value of a CV of a decoder connected to the programming track. In a next article you’ll learn how to implement this feature!

Demo

Here’s a video that shows how it is possible to modify the behavior of the led decoder programming its CVs using a laptop that runs the Rocrail application connected to a SPROG command station:

SerialDebug Library for Arduino

Serial-debug-app

Rui Santos over at Random Nerd Tutorials wrote a series of three posts on how to use the SerialDebug library created by João Lopes with Arduino IDE (programming Arduino, ESP32, ESP8266):

After programming the ESP32 using ESP-IDF, João noticed that debug for Arduino IDE needed some improvement. So, he created the SerialDebug library to bring better debugging to Arduino IDE. He also created a desktop application called SerialDebugApp that adds a UI and other useful functionalities.
To show you all the useful features of the SerialDebug library and the SerialDebugApp, he created three tutorials dedicated to this subject:

Part 1 – Using debug with levels
Part 2 – Simple Software Debugger
Part 3 – SerialDebugApp

See the full post on the Random Nerd Tutorials blog and the library GitHub repository here.

ESP32 (37) – https OTA

In the previous post of this tutorial, I explained how it is possible to update your board Over-The-Air thanks to a feature of the Freshen IoT dashboard.

Today I’ll show you how to update the firmware running on an esp32 chip using only components included in the esp-idf framework, without the need of any external tools or platforms.

OTA API

The esp-idf framework offers a set of native functions to implement, in your program, the ability to be updated over the air.

Those functions are grouped in the app_update component and to use them in your program you have to include the corresponding header file:

#include "esp_ota_ops.h"

Altough the use of the native functions is not very difficult (on Github you can find an example program), Espressif developers have added a component to the framework that makes it even easier the over the air update if the new firmware is located on a web site.

The component is named esp_https_ota.

esp_https_ota

The esp_https_ota component uses the OTA API to update the firmware of your board, downloading the binary file that contains the new firmware from a web site. As the name suggests, the only requirement (for security reason) is that the web site supports the secure version of the protocol (HTTPS).

The component is able to automatically identify an OTA partition in the flash memory that is not in use and to save the new firmware in that partition. It then configures the chip to boot from that partition:

https_ota_001

The use is very simple. First create an esp_http_client_config_t struct to configure the URL of the file with the new firmware and the SSL certificate of the server (or the certificate of the CA that signed it):

esp_http_client_config_t ota_client_config = {
  .url = "https://mysite.com/newfirmware.bin",
  .cert_pem = server_cert_pem_start,
};

You have to provide the certificate in PEM format. To store the certificate in your program, you can leverage the embedding binary files functionality of the firmware, as I already explained in a previous tutorial.

Then you only have to call the function:

esp_err_t ret = esp_https_ota(&ota_client_config);

to start the update process. If – when the process is complete – the ret variable contains a positive result (ESP_OK), you can reboot the chip to run the new firmware:

esp_restart();

A real application would probably need to periodically check if a new firmware is available and, only in that case, to start the update process. How can it be done?

In the program I wrote for this post and that is explained in the video below, I’m going to show a way widely used also in commercial products… enjoy the show ;)

as usual, the source code of the program is available in my Github repository

Tutorial: Git with Eclipse

egit-with-eclipse

A detailed tutorial on Eclipse with the EGit plugin by Erich Styger:

There are things which are game changer in the world of software development: one such event was when I started using a VCS (Version Control System): it changed for me how I keep and store my projects and settings. It even changed the way how I deal with non-software related items like documents or other valuable things: I started storing them in to a VCS too.

Via MCU on Eclipse.

Tutorial: Adding the SSD1306 OLED screen to an Arduino logger (without a library)

SSD1306 OLED screen on a DIY Arduino Based Data logger

Edward Mallon writes:

While I loved the Nokia 5110 LCD’s readability in full sun, the pressure sensitivity was a real problem for the underwater units. So I started noodling around with some cheap OLED screens from eBay.
With the exception of the init & XY functions (which are more complicated on the 1306 controller) the rest of the code ported over from the Nokia screen with no changes at all.  My guess at this point is that the shift-out method will work with most of the other cheap OLED screens, provided they don’t exceed the pin current limits implied by my method.

More details on Underwater Arduino Data Loggers blog.

ESP32 AM radio transmitter

am-modulation

A how-to on making a simple AM radio transmitter using the ESP32 microcontroller by Bitluni:

AM Radio transmissions are based on a carrier signal which is modulated by the audio signal. It’s a very basic principle but prone to noise from the environment. Using the ESP32 it is really simple to generate an analog signal using the built-in DACs. With the provided code here just a wire as an antenna has to be connected to the pin 25 of the ESP32. The transmission will end up on the AM frequency ~835kHz.

Via Bitluni’s Lab.

Check out the video after the break.