Reading a VGA monitor’s configuration data with I2C and a PocketBeagle


Ken Shirriff wrote an article showing how to read the monitor’s config data using the I2C protocol and a board with an I2C port:

Have you ever wondered how your computer knows all the characteristics of your monitor— the supported resolutions, the model, and even the serial number? Most monitors use a system called DDC to communicate this information to the computer.1 This information is transmitted using the I2C communication protocol—a protocol also popular for connecting hobbyist devices. In this post, I look inside a VGA monitor cable, use a tiny PocketBeagle (a single-board computer in the BeagleBone family) to read the I2C data from an LCD monitor, and then analyze this data.

More details at Ken Shirriff’s blog.

Curiosity Mars Rover


The Curiosity Mars Rover project from Beatty Robotics:

We are excited to share our latest and most ambitious robot, the Curiosity Mars Rover. This is a highly-interactive, 1/10th scale functional replica of the NASA Curiosity Mars Rover. This project was ambitious for us in two main ways: First, we worked very hard to make the robot visually accurate to the original NASA rover. This necessitated custom designing and manufacturing nearly every visible component on the robot. One of the key challenges was to get the required level of detail and functionality into such a small scale robot. Second, we encapsulated all the features and capabilities we wanted for this robot into a robust, maintainable, and modular electronics package based on a stack of custom Printed Circuit Boards (PCB) that we designed. This post focuses on the external view of the robot while future posts will focus on the electronics and functionality.

More details at Beatty Robotics blog.

STM32F103 vs GD32F103 round 3: UART


Here’s the part 3 of Sjaak’s post comparing the GD32 to the STM32:

Since the GD32F103 can run as fast as 108MHz but has not a proper USB clock divider to provide a 48MHz clock for USB communication we need another way to communicate with the outside world. Since the early days of computing the easiest way to go is a asynchronous serial interface using the UART peripheral. I can try to explain how this protocol works, but here is a better write-up.

If you missed part 1 and part 2, be sure to check it out.

More info at

ESP32 (33) – BLE, advertising

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.

Advertising process

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


Advertising DATA

It’s possible to tell the driver which data to include in the advertising packet with the following command:

esp_err_t esp_ble_gap_config_adv_data(esp_ble_adv_data_t *adv_data);

The command accepts as parameter a pointer to an esp_ble_adv_data_t struct:


The meaning of the different fields is explained in the Supplement to the Bluetooth Core Specification document.

First let’s find out how to transmit the device name. You have to use the esp_ble_gap_set_device_name() function to pass the name to the driver and set the field include_name to true in the struct:

static esp_ble_adv_data_t adv_data = {
  .include_name = true,

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:

static esp_ble_adv_data_t adv_data = {

Advertising PARAMETERS

After configuring the content of the advertising packet, you have also to tell the driver how to send the packet.

The command:

esp_err_t esp_ble_gap_start_advertising(esp_ble_adv_params_t *adv_params);

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:

  • minimum transmission interval: 0x20, maximum: 0x40
  • non connectable device (it doesn’t accept incoming connections and only sends data in broadcast)
  • public MAC address
  • transmission on all the 3 channels dedicated to advertising packets
  • no filter on devices who can perform a scan or connect
static esp_ble_adv_params_t ble_adv_params = {
  .adv_int_min = 0x20,
  .adv_int_max = 0x40,
  .adv_type = ADV_TYPE_NONCONN_IND,
  .own_addr_type  = BLE_ADDR_TYPE_PUBLIC,
  .channel_map = ADV_CHNL_ALL,
  .adv_filter_policy  = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,


I prepared a program that includes what explained above. The source code is available in my Github repository.

Here’s how it works:

App note: Enable pin operation and functions of eFuses


Get to know a number of useful usage of the enable pin of ON Semiconductor’s eFuse. Link here (PDF)

ON Semiconductor electronic fuses (eFuses) are analog integrated circuits that are used to protect circuits operating from 3.3, 5, or 12 V DC supplies. They have numerous protection functionalities such as overvoltage clamping, current limiting, thermal shutdown, and a controlled output voltage slew rate. They are available in thermal latching or thermal auto-retry configurations.

A key feature of the eFuse family is the enable pin. This application note describes the features of the enable pin and provides guidance to ensure its proper use. The enable pin of any eFuse may be left floating if the application does not require that it be controlled and does not require thermal fault notification.

App note: eFuse load current measurement


App note from ON Semiconductor on eFuse current measurement. Link here (PDF)

This application note describes the load current measurement solution for the eFuses which do not provide load current monitoring feature. Since almost all of the eFuses provide adjustable current limit functionality by utilizing an external current limiting resistor between “ILIM” and “SRC” pins, it is possible to connect a current sense amplifier across that resistor and measure the voltage drop across it which would be proportional to the load current. This method mainly requires a current sense amplifier and allows user to measure the system load current without introducing any additional resistance in series with the load path.

Arduino bootloader and ISP

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
  • reset
  • 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

isp-014 isp-015

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!


Testing the TPS61092 boost converter


Testing the TPS61092 boost converter from LuckyResistor:

For my current project I searched for a good boost power converter which is able to deliver continuous 400mA power for various sensors.
There are an endless number of good boost converters around, but not many can be hand soldered to a board. I would really like to see some like the TPS61092 with SOIC or similar packages. The biggest problem seems to be the heat transport, why most chips have to be mounted flat on the board.

Before using the chip in my project, I created a small test board. Using this board I can test various things. First I liked to test the performance under load. Next I tested if the chip can be hand soldered and finally I tested the final board layout I will use in my project.

More details at