Featured image of post week4

week4

embedded programming

Assessments book for this week:

Embedded Programming · GitBook (fabacademy.org)

Slides:

http://academy.cba.mit.edu/classes/embedded_programming/index.html

Group assignment

  • compare the performance and development workflows for other architectures

Individual assignments

  • browse through the data sheet for your microcontroller - program a microcontroller development board to interact and communicate - extra credit: use different languages &/or development environments

Files

servo.py servo_controler.py

To install a new board wich is not a “classic” arduino, we have to add it to the board library. Go to File>Preferences

image

add this url to “Additional cards” line, separate from the other with a coma https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json

image

Then in Tools>Card Type>Card manager, search for esp32 and click install image

Then select the right board under Tools>card type…>ESP32 Arduino> Xias ESP32C3

image

Compilation problem: As soon as I press the compile button, It seems to run forever and the computer start to lag. I finally found that the antivirus was in cause (Avira in my case). Temporarly disabling it fix the problem. I have to find a safer way to compile my sketches!

Xiao ESP32C3 characteritics:

Internal Schematics: https://files.seeedstudio.com/wiki/XIAO_WiFi/Resources/Seeeduino-XIAO-ESP32C3-SCH.pdf image

under the metal shield: image info from https://wiki.seeedstudio.com/XIAO_ESP32C3_Getting_Started/

image

There is even a battery connector, Indeed XIA ESP32C3 can use a 3.7V lithium battery as power input image

Testing the beast:

Everything hold in one hand! I wrote a simple sketch displaying a counter on a oled screen (video below). After that, I add a progress bar displaying the charge level of the battery (sketch here)

To monitor the battery, I add 2 200k resistor as explain in this schematic taken from seed-studio website, then read the analog value on A0

image

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
void setup(){
    Serial.begin(115200);
    pinMode(A0,INPUT);//ADC
}

void loop(){
    utint32_t Vbatt = 0;
    for(int i=0;i<16;i++){
        Vbatt = Vbatt + analogReadMilliVolts(A0); //ADC with correction;
    }
    float Vbattf = 2*Vbatt/16/1000.0; // attenuation ration 1/2, mV to V
    Serial.println(Vbattf,3);
    delay(1000);
}

Wireless communication

Testing ESPNOW example to communicate beetween two ESP32.

image

Now lets create a program by ourself

First get the mac adress of the ESP. To do that

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#include "WiFi.h"
 
void setup(){
  Serial.begin(115200);
  WiFi.mode(WIFI_MODE_STA);
  Serial.println(WiFi.macAddress());
}
 
void loop(){
}

The First MAc adress is 34:85:18:03:42:74 The second is: 34:85:18:03:75:BC

ESP32 as a file server

First, install SPDIFF support for esp32 folowing this tutorial https://randomnerdtutorials.com/install-esp32-filesystem-uploader-arduino-ide/

Install filesystem plugin https://github.com/me-no-dev/arduino-esp32fs-plugin

UPDATE: this plugin is not compatible with esp32-c3, we need to use this fork of the original plugins: https://github.com/lorol/arduino-esp32fs-plugin/releases

Download plugin .zip file and unzip the content into “tools” folder of your arduino sketch folder (can be found in IDE under File>Preferences) . image

Now the tool is available under Tools> ESP32 sketch Data Upload image

Using this tool, files inside “data” folder of a sketch will be uploaded to SPDIFF filesystem of the ESP32. image

Select SPIFFS to start upload. image

My template program use WifiManager. This library allow user to easily connect ESP to a Wifi network exhibiting an interface to scan and enter wifi password, without the need to enter/edit them into arduino sketch. https://github.com/tzapu/WiFiManager

image

UPDATE: Their is an incompatibilty using WifiManager. It complain about a conflicting wifi.h library image

I use another library named ESPAsyncWiFiManager https://github.com/alanswx/ESPAsyncWiFiManager

I found that after a first sketch upload i got an error and it was not possible to make other upload.

Solution seems to be: “some ESP32 boards need to be set manually into bootloader mode. On my board that would be pressing the RESET button and keep it hold, then press the USR button and keep it hold, then release the RESET button, then release the USR button. "

Not very handy….but works

For now Impossible to make this board working reliably.

RP2040

image image

Install RP2040 board support

In File>preferences>Additional cards...

add this line, seperate from other packages with a “,”
https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json

Then go in tools>Boards>Boards manager and look for “xiao” keyword image

Then select the right board

image

To control the builtin RGB led, We will include FastLed Library and control the led with this simple code:

MicroPython

https://www.framboise314.fr/demarrer-avec-seeedstudio-xiao-rp2040/

I will use Thonny to use the board with MicroPython. Go to Tools>Options, select RP2040, then the COM port exposed by your board image

We install MicroPython into the board. First we have to disconnect the com port if open clicking “Stop/restart backend”. Then click on Install or updateMicropython from the above windows. If the board isn’t detected, you can follow those steps:

  • Push and hold B button
  • Push and hold reset button
  • Release B, release Reset

image

This promp "»>” on the console show that micropython is installed correctly. image

Then we can write a python program an click on “run current script” button.

I decided to create a program that can move servomotors in a user defined sequence.

To do so, I first need a servomotor library wich just act as a wrapper aroud PWM standard library. I found it here: https://github.com/pvanallen/esp32-getstarted/blob/master/examples/servo.py

I upload it into the board enabling file explorer on View>Files then, creating a file, right click on it and click “upload to /”

A method “createSequence()” take in arguments a name and a list of servo positions and times.

1
2
3
4
sequence_list = [[servo_id_1, angle_1, start_time_1],
                 [servo_id_2, angle_2, start_time_2],
                 [servo_id_3, angle_3, start_time_3]...]
createSequence("Name of sequence", sequence_list)

test_sequence_1

My first movement sequence will be:

  • all servo to position 0
    • [0,0,0],[1,0,0],[2,0,0],[3,0,0],[4,0,0]
  • one after the other, all servo go to position 180
    • [0,180,500],[1,180,700],[2,180,900],[3,180,1100],[4,180,1300]
  • wait 2 second then all servo go to 90 at the same time
    • [0,90,3300],[1,90,3300],[2,90,3300],[3,90,3300],[4,90,3300]
  • all servo go back to 0 one after the other with a 1000ms delay
    • [0,0,5000],[1,0,6000],[2,0,7000],[3,0,8000],[4,90,9000]

I nest all those elements into a list and pass it to *createSequence().

image

then launch it with: start_sequence(“test_sequence_1”)

start_sequence method loop over the list and move specified servos at specified times.

To trigger movement, I first use machine.Timer to call callback method at specific time I got an annoying “[errno 12]: ENOMEM” error. image The solution found on stackoverflow was to type machine.reset() in Thonny console image Then relaunch the script. It seems to works. Finaly, I can’t succeed to make things works with Timer callback. I choose another way checking ellapsed time in a while loop and compare with the parameter start_time of the list.

1
2
3
4
ellapsed_time = time.ticks_ms() - sequence_start_time

if(ellapsed_time >= start_time)
    setPosition(angle, servo_id)

Here is a video of the console output. I don’t have an external power supply at home for the servomotors so I can’t record the result for now, but they moves as expected!

Now I could simply generate lists in script to create interesting paterns. For now, I connect 5 servos to an RP2040 board but I will scale it to at least 16 servo using a PWM multiplexer working in I2C like PCA9681 chip or use a raspberry Pi Pico wich have 16 PWM output available.

Add some light

We can use the builtin ws2812 adressable led for example: - confirm reception of a new sequence - blink if an error occur - display a color depending of servo requested position

First, we add the librarie for ws2812 led, we can found it on seedstudio website here Download the file and place it into the sketch folder, then right click and “upload to /” to send it to the RP2040 memory

Code

The code related to the light and servo position is bellow. Note that we record the current servomotor position (more precisely, the target position) into an angles list that we use later to update all led colors.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from ws2812 import WS2812
from servo import Servo

_sequence_holder = dict()

servos_gpios = [26,27,28,29,6,7,0]
angles =[0,0,0,0,0,0,0]

leds = WS2812(1,7,0.2) #7 leds on D7

def init_servos():
    for i in range(len(servos_gpios)):
        servo = Servo(pin=servos_gpios[i])
        servo.goto_angle(angles[i])
        servos.append(servo)

def setPosition(angle, servo_id = 0):
    angles[servo_id] = angle
    servos[servo_id].goto_angle(angle)

def display_leds_color_from_angle_and_servo_id(servo_id, angle):
    leds = WS2812(1,7,0.2) # I don't know why I have to set it again
    v = remap(angle,0,180,0,255)
    v = int(v)
    # going from red (angle=0) to blue (angle=180)
    color = [255-v,0,v]
    leds.pixels_set(servo_id,color)
    leds.pixels_show()

Then after each call to setPosition() I do a call to update_led_color_from_angles().

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy