Week 8 - Embedded Programming
"I am going to program my board using the Arduino as an ISP because I am not able to get my UPDI to work"
Description
This week we kick live into the boards that we made 2 weeks ago. We also try out several other boards to check how we can program them and what they are capable of.
Assignments - Learning Outcomes
# | Assignment | Fin |
---|---|---|
1 | Compare the performance and development workflows for different microcontroller families | 1 |
2 | Read the datasheet for the microcontroller you are programming | 1 |
3 | Program the board you have made to do something, with as many different programming languages and programming environments as possible. | 1 |
Spirals - Have you?
Spirals | Description | Done |
---|---|---|
A | Documented what you learned from reading a microcontroller datasheet. | 1 |
B | Programmed your board | 1 |
C | Described the programming process/es you used | 1 |
D | Included your source code | 1 |
E | Included a short ‘hero video’ of your board | 0 |
Assignment 1. Reading a Datasheet.
Reading a datasheet is not something one simply does.
What you basically do is that you use ctrl-f to look for a term that you need, or that you go to the index pages to find the chapter that most likely will contain the information that you are looking for.
The information you are looking for depends on what you are currently making, and therefor there is little sense in reading the datasheet cover to cover. Altough you probably will learn a lot from it and have a good sleep afterwards.
main takeaways from helicoptering over the ATTiny412 datasheet: - The sheet is not just for the ATTiny412, but for the entire tinyAVR® 1-series. - This means also the ATtiny212/214/412/414/416 - the differences between these different members of the same family is outlined in the datasheet on page 11 as follows:
Assignment 2. - Testing my own board
To test my own board I had to install the Megatinycore libraries and choose the ATtiny412 from the dropdown.
To quote Nadieh on this process:
There isn’t much in terms of “steps” to be found on the megaTinyCore website, except an almost hidden sentence that says “Choose Serial Port and 4.7k from the Tools -> Programmer menu, and select the Serial Port from the Tools -> Port menu”.
To test the board I hooked it up to my Mac
And then I used this code from Neil to test the board.
//
// hello.t412.blink.3.ino
//
// tiny412 blink hello-world, 3-pin UPDI+VCC header
//
// Neil Gershenfeld 1/10/21
//
// This work may be reproduced, modified, distributed,
// performed, and displayed for any purpose, but must
// acknowledge this project. Copyright is retained and
// must be preserved. The work is provided as is; no
// warranty is provided, and users accept all liability.
//
#define LED 4
void setup() {
pinMode(LED,OUTPUT);
}
void loop() {
digitalWrite(LED,HIGH);
delay(100);
digitalWrite(LED,LOW);
delay(100);
}
But at uploading the code to the board it failed:
Arduino: 1.8.13 (Mac OS X), Board: "ATtiny412/402/212/202, No (saves space), ATtiny412, 20 MHz Internal, 1.8V (5 MHz or less), Disabled/Disabled, EEPROM retained, Enabled (default timer), UPDI (pick this unless you have an HV UPDI programmer!), 8ms"
Sketch uses 686 bytes (16%) of program storage space. Maximum is 4096 bytes.
Global variables use 10 bytes (3%) of dynamic memory, leaving 246 bytes for local variables. Maximum is 256 bytes.
Traceback (most recent call last):
File "/Users/douweschmidt/Library/Arduino15/packages/megaTinyCore/hardware/megaavr/2.2.9/tools/prog.py", line 210, in <module>
main()
File "/Users/douweschmidt/Library/Arduino15/packages/megaTinyCore/hardware/megaavr/2.2.9/tools/prog.py", line 98, in main
return_code = pymcuprog_basic(args, fuses_dict)
File "/Users/douweschmidt/Library/Arduino15/packages/megaTinyCore/hardware/megaavr/2.2.9/tools/prog.py", line 138, in pymcuprog_basic
run_pymcu_action(pymcu._start_session, backend, device_selected,
File "/Users/douweschmidt/Library/Arduino15/packages/megaTinyCore/hardware/megaavr/2.2.9/tools/prog.py", line 107, in run_pymcu_action
status = func(backend, *args, args_pymcu)
File "/Users/douweschmidt/Library/Arduino15/packages/megaTinyCore/hardware/megaavr/2.2.9/tools/libs/pymcuprog/pymcuprog_main.py", line 538, in _start_session
backend.start_session(sessionconfig)
File "/Users/douweschmidt/Library/Arduino15/packages/megaTinyCore/hardware/megaavr/2.2.9/tools/libs/pymcuprog/backend.py", line 359, in start_session
self.programmer.setup_device(
File "/Users/douweschmidt/Library/Arduino15/packages/megaTinyCore/hardware/megaavr/2.2.9/tools/libs/pymcuprog/programmer.py", line 78, in setup_device
self.device_model = get_nvm_access_provider(self.transport,
File "/Users/douweschmidt/Library/Arduino15/packages/megaTinyCore/hardware/megaavr/2.2.9/tools/libs/pymcuprog/nvm.py", line 42, in get_nvm_access_provider
accessprovider = NvmAccessProviderSerial(transport, device_info, baud=frequency)
File "/Users/douweschmidt/Library/Arduino15/packages/megaTinyCore/hardware/megaavr/2.2.9/tools/libs/pymcuprog/nvmserialupdi.py", line 53, in __init__
self.avr = UpdiApplication(port, baud, self.dut)
File "/Users/douweschmidt/Library/Arduino15/packages/megaTinyCore/hardware/megaavr/2.2.9/tools/libs/pymcuprog/serialupdi/application.py", line 75, in __init__
datalink.init_datalink()
File "/Users/douweschmidt/Library/Arduino15/packages/megaTinyCore/hardware/megaavr/2.2.9/tools/libs/pymcuprog/serialupdi/link.py", line 45, in init_datalink
raise PymcuprogError("UPDI initialisation failed")
pymcuprog.pymcuprog_errors.PymcuprogError: UPDI initialisation failed
pymcuprog.pymcuprog_errors.PymcuprogError: UPDI initialisation failed
This report would have more information with "Show verbose output during compilation" option enabled in File -> Preferences.
The same error is also produced when there is no board attached to my computer. So it seems the computer can't find the UPDI...
At this point I am not really sure what is causing my tests to fail. And I decide to
- insert a debugging table.
- watch the recitation on debugging.
Debugging Table for the issue that I am unable to program my 'Hello World' board from my mac using my own UPDI.
Issue in pictures:
There is no USB device showing in the Arduino app under the serial ports when I connect my UPDI.
The UPDI is clearly listed in System Profile .
# | Problem | Hypotheses | Debugging | Main issue solved? |
---|---|---|---|---|
1 | The UPDI is recognized by my Mac (as shown in the system profile), but not by the Arduino program. | There are missing libraries I need to install for Arduino.app to recognize the UPDI | Looking online for similar issues. | 0 |
2.1 | There seem to be no libraries for UPDI in arduino | The problem lies elsewhere | There is a video by Aalto Fablab in which they talk about pyupdi; a program to talk to your updi. Maybe this solves my problem. I follow the steps to get pyupdi going. | 0 |
2.2 | The hex file at 13.14 is not created | I made a mistake in the preference path | check the video again. Indeed at 9:51 he has the same capitalization error. I just didn't notice it. Now fixed. | 0 |
2.3 | There is no pyupdi.py file in my download. |
In a recent commit the contents of the gitrepo has changed | it seems that this merge has changed location of files in pyupdi. I use the code before that commit and carry on. |
# | Problem | Hypotheses | Debugging | Solved |
---|---|---|---|---|
3 | using $ ls /dev/tty.*/ (as Kris does in his video) my UPDI is not showing up. |
This is odd as, as mentioned before, the device does show up in the system information program | More searching is needed | 0 |
6 | UPDI still not showing up | The problem is in my Mac. | I try another Mac (an imac2009) and my Ubuntu Laptop. On both these devices I am unable to get the UPDI to show. On the iMac it is the same problem as on my Macbook. On the Ubuntu laptop I am not sure, as I am not very good with Linux | 0 |
7 | UPDI still not showing up | I bring the UPDI to the fablab at Waag | Henk connects it to a ubuntu machine and Is able to make it show up. Henk is convinced the problem is in my laptop. | 0 |
8 | My Mac might not recognize the UPDI | My UPDI is fine, it is my Mac. | So I borrow Nadiehs UPDI to verify. Indeed her UPDI also does not show up | 1 |
9 | My Mac is unable to recognize FTDI/UPDI devices. | If I can get a certified board working on my mac I am able to program my own board again. | I borrow an FTDI cable from Henk to test if this works. | 0 |
10 | Issue persists Board/cable shows up in System Profile, but not anywhere else. | There is a privileges issue. | Will make a new (admin)user account on my mac and try from there | 0 |
11 | Still the same issue. | There is a driver issue. People on the internet are talking about this | I will follow the thread and see what comes out of it | 0 |
12 | FTDI devices not listed in /dev/ | My wacom tablet driver is preventing both the FTDI VCP driver and apples VCP driver from attaching to devices and providing a COM port in the '/dev' folder. | Entirely wipe wacom from my macbook solved the issue | 1 |
Programming the board.
Now that te UPDI is showing up, I can start using it to program my Hello World board! Or so I thought...
I connect both to my computer. The Hello World has two pins (remember the one I soldered wrong?) on one side and six pins on the other side.
The two pins are used for programming, in this case, and connect to the UPDI. One is GND one is UPDI.
Of the six pins only two are used for powering the hello world board. Using jumper cables I connect them to an old USB to TTL board I still had laying around. This old board has clear indications of GND and 3.3 and 5v output so I know where to connect the pins w/o the need of a datasheet.
Other people refer to this board as an FTDI board.
I use the lovely video of Aalto Fablab already mentioned above to guide me through the process. And this time I get to the point where I upload the code to my programmer and this error appears.
./pyupdi.py -d tiny412 -b 19200 -c /dev/tty.usbserial-D30A3T7O -f ~/Documents/Arduino/build/t412blink.ino.hex -v
INFO:phy Opening /dev/tty.usbserial-D30A3T7O at 19200 baud
INFO:phy send 1 bytes
INFO:phy data: : [0x0]
INFO:link STCS 0x08 to 0x03
INFO:phy send 3 bytes
INFO:phy data: : [0x55, 0xc3, 0x8]
INFO:link STCS 0x80 to 0x02
INFO:phy send 3 bytes
INFO:phy data: : [0x55, 0xc2, 0x80]
INFO:link LDCS from 0x00
INFO:phy send 2 bytes
INFO:phy data: : [0x55, 0x80]
INFO:phy receive : []
INFO:link UPDI not OK - reinitialisation required
INFO:phy Sending double break
INFO:phy Opening /dev/tty.usbserial-D30A3T7O at 19200 baud
INFO:link STCS 0x08 to 0x03
INFO:phy send 3 bytes
INFO:phy data: : [0x55, 0xc3, 0x8]
INFO:link STCS 0x80 to 0x02
INFO:phy send 3 bytes
INFO:phy data: : [0x55, 0xc2, 0x80]
INFO:link LDCS from 0x00
INFO:phy send 2 bytes
INFO:phy data: : [0x55, 0x80]
INFO:phy receive : []
INFO:link UPDI not OK - reinitialisation required
Traceback (most recent call last):
File "/Users/douweschmidt/Dosch.it/Fabacademy/pyupdi/./pyupdi.py", line 182, in <module>
_main()
File "/Users/douweschmidt/Dosch.it/Fabacademy/pyupdi/./pyupdi.py", line 95, in _main
nvm = UpdiNvmProgrammer(comport=args.comport,
File "/Users/douweschmidt/Dosch.it/Fabacademy/pyupdi/updi/nvm.py", line 17, in __init__
self.application = UpdiApplication(comport, baud, device)
File "/Users/douweschmidt/Dosch.it/Fabacademy/pyupdi/updi/application.py", line 17, in __init__
self.datalink = UpdiDatalink(comport, baud)
File "/Users/douweschmidt/Dosch.it/Fabacademy/pyupdi/updi/link.py", line 32, in __init__
raise Exception("UPDI initialisation failed")
Exception: UPDI initialisation failed
INFO:phy Closing port '/dev/tty.usbserial-D30A3T7O'
The part where it says UPDI initialisation failed
is an indication of an hardware failure... Several online searches only bring results of previous Fabacademy students having the same issues.
As I still have the other programmer of Henk lying around from my previous tests, I am now going to use that to try to program my board. The repairing of my own board will have to wait a little.
Embedded programming.
For these steps I basically follow the steps that Nadieh already made and the video of Neil.
I do not really know what I am doing, but so far we have this:
- A working Hello World board. (confirmed as Nadie already made the light blink oon thursday)
- Arduino app installed with all the megatinycore library installed
- A broken UPDI that has been temporarily replaced by a working one.
- Pyupdi installed.
- Wacom drivers removed from my system
- A bunch of different code samples from neil.
I first try the 'Hello World' echo code sample from Neil.
Using the Arduino application I compile and upload the data to my board. Now that I have a working UPDI, this is no longer an issue. Just select the right processor, port and programmer and off you go.
It turns out that I already have pyserial and miniterm on my Mac. This was probably part of the pyupdi installation. I can enter the hello world board without any problems. But running the 'hello world' echo poses a bigger challenge.
There is no response. I am shouting into the void.
Maybe I am overreaching and should first try to get the LED blinking...? For this I use the standard example code build in the Arduino app. This compiles nicely and uploads without a hithc, but there is no blinking LED when done.
Continuing reading Nadiehs docs, I learn that you have to specify which LED you want to blink and the piece of code that does work. For comparison, I put them here side-by-side:
You can observe that Nadies has added a line to define which leg of the AtTiny the LED is attached to.
#define led_pin PIN_PA6 // This uses the ATtiny pin number
//const int led_pin = 0; // This uses the Arduino pin number instead
The word led_pin
return later in the code where se changed LED_BUILTIN
to led_pin
pinMode(led_pin, OUTPUT);
The rest of the code stayed the same. And indeed, on both my hello world boards the LED starts blinking when I run this code.
This is also nice to know that the initial board I made works just fine...
It is not so nice that I simply copy-pasted code, and still don't really know what to do myself... I am starting to get a little bit frustrated...
Hello void...
Lets return to the Hello World thingie from above. Altough all code uploads just fine, the board refuses to hello world to me. And in the meantime a night has passed. I m currently in my home without a working UPDI. I thought I could be smart and use another programmer instead.
My thoughts:
- My hello world board needs power. The red cable it attached to 5V. The brown to GND. Power is there!
- The board needs to be programmed. There is a Rx and a Tx pin on my programmer; I just need to attach these to my Hello World Board!
- Profit
Reality:
- The pins that I would connect to my UPDI are labeled: UPDI (doh) and the other one is, also visually, connected to GND.
But... looking back at my schematics, I do see Tx and Rx labels on the ATTiny412 chip... Now I could just connect my programmer to those.... right? Henk and Neil and all the others want us to use the UPDI so they didn't tell us that this is also possible... but I found it out anyway! Hahahahaha. Boy, I smell pretty...
Like this!
You see, the LED is already blinking with joy. So the power is on there. Let's make sure all the settings are right; correct board, baud rate and what have you now.
Now lets upload a sketch.
Things are not what they are supposed to be according to me. Reality is having a stronger grip on things then I agree.
Anyway... There is a a lot of stuff out there on the internet about how to do this sort of stuff. I think there is nothing left for me but to repair my UPDI and come back to this at a later stage. So I search for the issue online and find a blog by a last year student who ran into the same issue.
I know I am not supposed to do the following, but I want to program my hello world board. So I am going to use an Arduino to do it.
Finding VIN
Most steps went fine. Just when I was about to upload the program, I had to connect one cable to VIN
.
What the hell is VIN
? I searched through the ATTiny412 datasheet and found the word Vin only used in contextx on Voltage In
. It was not mentioned near the ports/legs.
Then I closely inspected the image in which she is showing how to connect the wires and I found that, by cross checking against her schema, that she is probably talking about VCC. VIN is probably a typo...
Altough it is weird that she talks about VIN in both her text and also in her images... Maybe VIN just means VoltageIn and is an synonym for VCC... Well, here goes nothing. Ready to smoke test!
Sadly also here I enter the sandbox of Attiny programming and come to a grinding halt.
back to the UPDI.
I am now back at Waag and Henk is trying to get my UPDI working again. The longer it takes him, the happier I am. I feel sorry for him, but it is really frsutrating if you are unable to fix something for days and then someone else fixes it in 20 seconds. So, for my mood it is good that he is, so far also unable to find the issue. It is now 10:44, we have 16 minutes left untill local class starts.
Henk is debugging my board, he gave me another UPDI, and I am going to try now to see if I can get an echo out of it.
Current status
Nothing has really changed for me. I am stuck with an Arduino that uploads the code just fine and a stable miniterm connection to my Hello World board. But no echo.
Oh well... Time for class... Let's hope that Neil doesn't pick me... 🙏
6 weeks later...
As Henk has caught up with his assessment, I now have to complete this week. Luckily I can use the experience we've gained in those 6 weeks to get the board working now. Also, having a working UPDI, that Henk gave to me, also helps. I should make a new UPDI once I have time...
Long story short.
When you have a WORKING UPDI, you can use that to connect to your hello world board.
and if you then open mini term and type hello world
and nothing happens...
it probably means you got Tx and Rx the wrong way around.
Also, you don't really need miniterm. Eventhough it looks cool. You can also use the Arduino serial monitor..
The only thing you now have to do is to ignore that the letters are under each other... and not nicely next to each other. But the board is hello worlding!
Oh yeah, and another thing could be to get the sensor on there working...
Assignment 3. Group assignment.
- What is the difference in workflows between the different boards https://www.elprocus.com/different-types-of-arduino-boards/
name | specs | comment |
---|---|---|
ArduinoYUN | ||
ESP36Camera | ||
ESP82 | ||
Olimex | ||
Fabschoolino |
Make the Arduino YUN work.
- connect the board over USB to your computer
- select the right board in the arduino program.
- check that the right port is selected.
- choose a build-in test program from the Arduino list.
- compile and upload the program
- works!
By carefully reading and comparing different test samples you could start making your own scripts. So Far I haven't...
We also tested it with a breadboard. For this I used this tutorial by James Brown
Note that I did not really look up how the resistor should be placed: I just kept turning it until it worked.
Fabschoolino
The Fabschoolino is an Arduino clone made by Waag. It is meant to be assembled by kids and has a powersource so it can be tested without access to a computer. I assembled mine in a meadow a couple of years ago during SHA2017. Connect to mac using serial cable from Henk. Tx, Rx, GND and VCC can all be connected to USB.
I followed the excellent manual available at http://fabschoolino.waag.org/ to make a LED blink. No biggie.
ESP32 Cam
As I did not have any access to a working UPDI on the last day of the week, I decided to try to program the ESP32Cam. I did this for two reasons:
- I might want to use a ESP32 kind of MC in my end project.
- I hope I can translate any learning from the ESP32 to my own ATTiny412
To start with the ESP32, you need some prerequisites set up. I followed a Youtube tutorial by the DroneBot Workshop for a big part.
You need to install the third party library to Arduino, just like with megatinycore. And then you need to pick the right board from a long, unsorted, list of boards.
Some characteristics of the ESP32- Dualcore 32 bit microcontroller - Dual core, 32bit microcontroller module - CPU cores can be individually controlled - Clock frequency to 240MHz - Multiple power modules - Integrated Wifi, Bluetooth and BLE - Multiple digital and analogue pins - 18 analogue to digital converters - 2 8 bit digital to analogue converter - 10 capacitive touch sensor inputs - 4 SPI bus channels - 2 I2C bus connection - 2 I2S bus connections (this can carry audio) - 3 UARTS
It can be made to - SD card host controller - IR REmote controller - Motor PWM - LED PWM (16 channels) - Hall effect sensor - Ultra low power preamp - multiple low power clocks
The board has so many capabilities that some pins have multiple functions. This means that some uses may conflict and not everything can be used at the same time.
Using the ESP32CAM with Arduino tutorial
The Library for the ESP is not installed by the Arduino program. You need to add the repo to the program.
NOTE After you added the link to the repo in the program, it is good to restart the program in order for the library to load. And then when the library is downloaded, you need to restart the program AGAIN for the program to load the newly added board.
Uploading code issues
- set the right port in tools menu
- Time out issue:
Arduino: 1.8.13 (Mac OS X), Board: "ESP32 Wrover Module, Huge APP (3MB No OTA/1MB SPIFFS), QIO, 80MHz, 921600, None"
Sketch uses 2593694 bytes (82%) of program storage space. Maximum is 3145728 bytes.
Global variables use 56280 bytes (17%) of dynamic memory, leaving 271400 bytes for local variables. Maximum is 327680 bytes.
esptool.py v3.0-dev
Serial port /dev/cu.usbserial-0001
Connecting........_____....._____....._____....._____....._____....._____....._____
A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header
A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header
This report would have more information with "Show verbose output during compilation" option enabled in File -> Preferences.
Turning on "Show verbose output during compilation" makes no sense as the error takes place during uploading. Not during compilation.
... this could also be because I did not use an "ESP32 ESP8266 programmer USB to serial converter"...
There is a nice little schematic in the video on how to connect it.
The instructor stressed multiple times to set the jumper to 3.3 volt. I can't do this on my programming board. I am still unsure what programming board I actually have... But it works just fine... Here is a nice picture of it:
For this test I am using one of the build-in examples. This is a nice, and also usefull example; a sketch that can turn the ESP32 cam into a webserver that streams images over your LAN. It also has some settings as we will shortly see. It took some digging to find the right example. This is why I like MacOS: the search function also works for menu items...
After we got the right sketch, choose the right board and set the port to serial, we can start compiling and uploading.
Success! The last lines in the code say:
Leaving...
Hard resetting via RTS pin...
I also saw a new device appear in the network with the name espressif
.
Using the build-in serial monitor tool of the Arduino app I found that the webserver ip is actually not the same as the device IP address. But when I connected to that I was able to ind the webserver, connect to it and see images. The quality is really low... From the serial connection I read that the framerate is embarrassingly low, causing the low quality.
I tried to switch from 3.3V to 5V and connect the ESP32Cam to a power USB hub to see if it was a power issue, but the low quality stayed.
This will mos def make a nice hedgehog wildcam. When time and space allows...