Felix writes, “I posted a short illustrated guide for making your own Moteino from SMD components. It also includes details how to burn the bootloader and fuses. Check it out here. Thanks and credit goes to forum user LukaQ for his contribution of the images and test sketches in this guide!
Dejan Nedelkovski over at HowToMechatronics shared detailed tutorial on how servo motors work and how to control servos using Arduino and PCA9685 PWM driver:
There are many types of servo motors and their main feature is the ability to precisely control the position of their shaft. A servo motor is a closed-loop system that uses position feedback to control its motion and final position.
In industrial type servo motors the position feedback sensor is usually a high precision encoder, while in the smaller RC or hobby servos the position sensor is usually a simple potentiometer. The actual position captured by these devices is fed back to the error detector where it is compared to the target position. Then according to the error the controller corrects the actual position of the motor to match with the target position.
In this tutorial we will take a detailed look at the hobby servo motors. We will explain how these servos work and how to control them using Arduino.
In the previous posts I explained how to receive and send advertising packets based on the Bluetooth LE standard.
The payload (that is the amount of “useful” data) of those packets is at most 31 bytes. It isn’t much: if – for example – you want to include the device name, little place remains for other data.
The BLE standard allows peripherals to send additional data using the scan request – scan response process.
When a device receives an advertising packet, it can contact the transmitter by sending a scan request packet to request further information. When receiving a scan request package, the peripheral can respond with a scan response packet:
Advertising and scan request packets have the same format; it’s therefore possible to transfer, using scan response, additional 31 bytes of data.
The esp framework offers two modes for configuring the content of a scan response packet: using the esp_ble_adv_data_t struct or creating a byte array (raw mode). These modes are similar to the ones used to configure advertising packets you learned in previous articles (struct and raw mode).
In the first case, you have to declare a second struct, in addition to the one related to the advertising packet, to define the content of the scan response packet:
Very important is set to true the set_scan_rsp parameter. It’s indeed this parameter what tells the driver that this struct is related to the scan response packet.
You can then pass the new struct to the driver, with the same function used previously:
The driver will call the callback function twice: one to indicate the successful configuration of the advertising packet and one for the configuration of the scan response one. The two events are different:
case ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT:[...]case ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT:[...]
You have to wait until both the events have triggered before starting the advertising process. In my example program (you can download the source code from my Github repository) I use two booleanvariables:
If you want to use the raw mode instead, you have to declare a byte array and fill it with the content of the payload of the packet. Then you can use a specific function of the framework to pass the array to the driver:
When using this new function, it also changes the event that the driver passes to your callback function when the configuration is complete. The new event is ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT. As in the previous example, when this event is triggered you can start the advertising process:
For the advertising process to work, the data contained in the array must correspond to a valid payload.
The payload contains one or more AD (advertising data) structures. Each structure is made by 3 fields:
an initial byte that represents the length (in bytes) of the structure, excluding itself
a byte that represents the type of the data contained in the structure
a variable number of bytes which are the actual data
The codes that can be used to define the type of data can be found in the Bluetooth specifications. Depending on the type of data, it is then necessary to apply a particular format to the data that follows. The necessary information is found in the Core Specification Supplement document (available on the Bluetooth.com website).
Let’s see a simple example: the ADType 0x09 represents the complete local name, which is the name of the device. This name must be specified in AD data with simply a sequence of the ASCII codes that correspond to the different letters.
Afroman writes, “Electrolytic capacitors are common, but knowledge of their limitations is uncommon. A demonstration is shown highlighting the difference in performance between electrolytic and ceramic capacitors in power supplies. Other topics discussed in the video: Electrolytic capacitor construction, ceramic capacitors, ESR, ESL, impedance curves, why “0.1uF”, and more.”
Rui Santos writes, “In this project, you’re going to learn how to control the ESP8266 or the ESP32 with voice commands using Alexa (Amazon Echo Dot). As an example, we’ll control two 12V lamps connected to a relay module. We’ll also add two 433 MHz RF wall panel switches to physically control the lamps.”
In the previous posts you learned how to use the esp32 chip to receive and parse the advertising packets transmitted by BLE peripherals. As a practical example, I developed a program to detect the presence of a particular iBeacon and activate an output accordingly.
In today’s tutorial, you’ll learn how to transmit advertising packets instead.
You’ve already discovered that the Bluetooth driver included in the esp-idf stack is executed in a dedicated thread. Whenever the driver needs to send a notification to your program, it calls a callback function indicating which event has triggered.
The advertising process is very simple:
the program configures the data to be transmitted with esp_ble_gap_config_adv_data()
the driver reports that it has finished the configuration with the event ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT
the program can now start the advertising process with esp_ble_gap_start_advertising()
the driver reports that the process has started with the event ESP_GAP_BLE_ADV_START_COMPLETE_EVT
It’s possible to tell the driver which data to include in the advertising packet with the following command:
Using the flags, you can publish some features of your device. The available constants are:
you can combine them with the OR operator. If, for example, you want to tell the world that your device is limited discoverable (i.e. it sends the advertising packets only for a limited time, usually 30 seconds) and that it doesn’t support classic Bluetooth (BR/EDR, Basic Rate/Enhanced Data Rate) you’ll write:
accepts as parameter an esp_ble_adv_params_t struct:
You can configure the minimum and maximum transmission interval of the packet. The two parameters can assume a value from 0x20 to 0x4000. To calculate the interval in milliseconds, the value specified must be multiplied for 0.625. This means that the minimum value (0x20) corresponds to an interval of 12.5ms.
The esp_gap_ble_api.h file lists the constants that can be used for the other parameters (esp_ble_adv_type_t, esp_ble_addr_type_t …).
For example, let’s configure the advertising process as it follows:
After having developed a sketch using the Arduino IDE, you can compile and load it on the Arduino board connected to your PC with just a click on the upload button:
The program is stored in the flash memory of the microcontroller (on Arduino Uno boards this is the ATmega328p).
You can upload your program on the microcontroller without the need of a dedicated programmer because of the microcontroller itself runs a small program named bootloader.
The bootloader is indeed a program, already flashed in every microcontroller of the Arduino boards, that is executed everytime the microcontroller is reset. The first operation the bootloader does is to check if on the serial/USB connection there’s a request to flash a new program. If so, the bootloader talks with the Arduino IDE, receives the new program and stores it in the flash memory:
The bootloader used as of now on the Arduino Uno boards is named optiboot.
If you buy an ATmega328p chip and you want to upload your sketches on it using the Arduino IDE you have first to flash the bootloader in the chip. You usually need a dedicated programmer to program the chip. ATmega microcontrollers support a programming method named In System Programming (ISP), designed to program the chips directly on the board where theyt are located.
This method requires to connect 6 pins of the chip to the programmer:
5V and ground
MISO, MOSI and SCK
For example every Arduino Uno has a dedicated connector which allows to re-program the ATmega328p chip without removing it from the board:
On the Internet you can find several ATmega programmers (for example this by Adafruit); very interesting is the possibility to use an Arduino as a programmer, thanks to the work of Randall Bohn.
First you have to upload on your Arduino the ArduinoISP sketch which is included in the Examples shipped with the IDE:
then you have to create – for example on a breadboard – a minimal circuit with the chip to be programmed, a 16MHz crystal and two 22pF capacitors:
using some jumpers, connect your Arduino Uno to this circuit as it follows:
5V -> pin 7 and 20
Ground -> pin 8, 22 and the two capacitors
pin 10 of Arduino or RESET of the ICSP connector -> pin 1
pin 11 of Arduino or MOSI of the ICSP connector -> pin 17
pin 12 of Arduino or MISO of the ICSP connector -> pin 18
pin 13 of Arduino or CLK of the ICSP connector -> pin 19
Configure the IDE to use Arduino as programmer:
then burn the bootloader:
after few seconds, the IDE should confirm that the bootloader was programmed on the chip:
On some webstores I found an Arduino shield which makes it simple to program ATmega chips. It’s named AVR ISP Shield and manufactured by a company called “OPEN-SMART”:
This shield has a ZIF (Zero Insertion Force) socket where the chip goes, some pins to connect it to external boards and a buzzer that is used to confirm the burn process with two beeps.
On the Internet I found an archive with the documentation about this shield and the “official” sketch. You can also use the sketch shipped with the IDE, it won’t only activate the buzzer when the burning process ends successfully.
If you need to program several ATmega328p chips (for example if you’re building your Arduino-compatible boards) the use of this shield makes the programming process much easier and faster!
Continuing the DIY Arduino tutorial series, this AddOhms episode shows how to create a PCB in KiCad. I make a joke that the original design was a rectangle, which I found boring and pointless. So instead, I designed a triangle to give the board 3 points. Get it? Puns! I am calling it the Pryamiduino. To be honest, I found not having a constraint to be a problem. By forcing a specific board size and shape, many decisions were more manageable.
In my previous article I explained the Bluetooth Low Energy technology and the advertising process.
You learned that a BLE device can leverage the advertising packets to send data; in this case the device is called broadcaster and the devices which receive data are called observers.
The payload of an advertising packet has the following structure:
ADV ADDR is the device MAC address (this is the address displayed by the program developed in the previous article) and ADV DATA is a field, with a max length of 31 bytes, that contains one or more structures, each with 3 elements:
AD length is the total length (in bytes) of each data structure
AD type is the type of data contained in the structure
A device, for example, can transmit its local name using the AD type 0x09:
In scan mode, the Bluetooth driver returns to the program the received data (ADV DATA) in thescan_result->scan_rst.ble_adv array. This array contains uint8_t values and it’s size is scan_result->scan_rst.adv_data_len.
The Bluedroid library contains a method, esp_ble_resolve_adv_data(), which allows to get the value for a specific AD type passing the raw data. The header file esp_gap_ble_api.h contains definitions for the most common AD types:
In my Github repository you can find an updated version of the scan program. Thanks to what explained above, now the program can also display – if available – the name of the device:
A particular family of broadcaster devices are the iBeacons. These devices have been designed by Apple to allow interaction with IOS devices (iPhone …) based on location awareness. Let’s make an example: an iPhone can “notice” that it is close to a particular iBeacon, associated with a room in a museum, and therefore offer the user a brief guide to the exhibited works.
iBeacon specifications are available on Apple’s developer portal. iBeacons work transmitting advertising packets with specific payload (ADV DATA):
The first structure has AD type = flags (0x01). Each bit has a different meaning, usually iBeacons use 0x0A value for AD data.
The second structure has type = 0xFF, that is Manufacturer Specific Data. The Bluetooth standard allows the different manufacturers to use this ID to transmit custom data. The total data length is 25 bytes (0x1A – 0x01 that is the length of the AD type field).
Apple specifications further subdivide the AD data field in several elements:
The first field is the manufacturer/company; iBeacons normally use the code 0x004C, assigned to Apple Inc. The next two fields define the iBeacon type and have a fixed value (0x02 e 0x15). The UUID field, together with the Major and Minor ones (optional, they can have a value of 0) uniquely identifies each iBeacon. (insieme con i campi Major e Minor (facoltativi, possono essere impostati a 0) identificano univocamente il singolo iBeacon. Finally, the TX power field contains a measurement, one meter away from the iBeacon, of the received power and is useful for precisely estimate the distance between the phone and the iBeacon itself.
I developed a program for the esp32 chip which turns a relay on if it detects a specific iBeacon. Via menuconfig you can configure the UUID of the iBeacon which triggers the led, the pin the led is connected to and the timeout – in seconds – after which the program turns the led off if the iBeacon is not detected anymore. You can moreover set a power threshold to control the distance at which the iBeacon is detected.
To parse the received packet and get the UUID value, in my program I used the method described in this article (parsing using astruct).
The program verifies if the received packet (event ESP_GAP_SEARCH_INQ_RES_EVT) was sent by an iBeacon checking that the packet length is 30 bytes and that its header contains the values listed above: