Material for possible pojects with Microcontrollers
As you know you can prepare a project with microcontrollers for the exam of this course. We have bought some more periphal hardware for these project which you can borrow to make such a project. We do not have from every item enough to give it to every student (and there are usually also many students doing a project with FPGAs) but all of the items are fun to work with and hopefully everybody will find something for his ideas.
In this section we give links to the documentation and data-sheets of these items so that you can look up the details of how to use them in your program.
I2S microphone
A small microphone incuding a chip with an ADC (Andalog to Digital Converter) and an I2S encoder. I2S is a serial protocol with only two lines designed for transmitting high quality stereo audio data. The ESP32 has a peripheral for this protocol and can directly receive the output of the microphone.
Datasheet of INMP441 microphone
Step motor with driver
We have a simple step motor with a small driver chip which simply contains "Darlington Transistors" to interface the output of the microcontroller to the coils of the step motor. The step motor coils need to be driven with currents which the microcontroller cannot provide. Therefore an amplification stage is needed for this purpose. The Darlington Transistors are simply two transistor amplification stages in a row. In addition the circuit contains protection diodes which make sure the transistors are not destroyed if the current through the coils of the motor is swithced off and a voltage spike due to the induction of the coil is generated in the motor. (This is common practice for driving inductive loads like motors and relays).
Data sheet of the driver chip ULN2003
Data sheet of the motor 28BYJ-48
Since there is not much info in the datasheet of how to use the motor, here some more links:
General info for driving the motor with an Arduino
Of course there are also libraries on the web, to control the motor. But it is much more fun to program this yourself and you learn more. To make the motor rotate you have to power the coils in a specific sequence. The coils are numbered such that when you power them one after the other the motor starts turning step by step. You can generate smaller steps by not changing from powering coil n and then n+1 but you put an extra step in between where you power both coils.
Be sure of two things: Use an extra power supply to power the motor, since it draws a lot of current, and be careful to not go through the sequence of steps too quickly, otherwise the motor cannot follow. The data sheet says 100Hz for the frequency in normal operation. Idle in traction frequency means that if there is no load on the motor, it will start turning with frequencies up to 600Hz. During operation you can even go to 1000Hz if there is no load (Idle out traction frequency).
There are many links on the internet for this motor.
Servo motors
Servo motors are used to mechanical positions. They are well known in the world of remote controlled models where they control the steering of a car, or a boat or the rudders of a model plane. Normally in the Servo there is a motor which is connected to gear mechanim which is finally connected to some kind of lever arm which should be precisely positioned.
A servo motor has a control line via which control signals transmitted from a control module (i.e. a microcontroller) to the servo. The signals carry in some form the information of the position which the servo motor should go to.
There are different implementations of a servo. There are digital servos which receive digital data over the control line and adjust a step motor accordingly.
Cheaper models which are wide spread in the world of remote controlled models, have a standard motor inside, but the position of the lever arm is connected to a potentiometer so that an analogue voltage proportional to the position of the lever arm is created. The control signal is a pulse of variable width. The pulse length is proportional to the position of the lever arm. Hence the pulse width is converted to an analogue voltage which is then compared to the analogue voltage of the potentiometer. This meachnism generates a differential signal which is used to steer the motor in the position where the potentiometer voltage and the voltage derived from the pulse length are equal.
The standard pulse width is from 1 to 2 ms, and should be repeated every 20-50 ms. 1.5 ms pulse width will put the servo in the middle of its range, with 1 ms to one end and 2 ms to the other. Some servos can go a little farther in response to values a little past the 1-2 ms range.
In micropython you can use the machine.PWM
class to implement these pulses.
Pmod I2S2 audio in/out module
This module provides an analogue audio input and converts the audio signal to a I2S stream which can be fed into the microcontroller, and an analog audio output which can be fed from a microcontroller I2S stream. Levels are such that a headphone can be plugged in the output (but no speakers). You can also try to plug the output in your computer audio/mic input. If you plug an analog microphone into the input it might be that the level is too low.
The module is documented on the webpage of the producer:
When operating this module be aware that it needs the master clock being provided by the microcontroller (many other I2S modules do not need this clock).
TFT displays based on ST7735 controller chip
We have two different 1.8 inch TFT displays which can be used to implement screen output. One of the modules also contain an interface to a SD card. It simply breaks out the pins necessary to communicate with the SD card via SPI or MMC (another protocol for SD cards).
The datasheet of the ST7735 controller can be found here:
Information on the display and how to use it can be found on the LCD Wiki:
It is possible to write a driver from scratch. However, there are also drivers in the open source community which can be used. Not all of these work. The reason is that a driver needs to "know" how the tft display matrix is connected to the controller chip (this is exactly the same as we have discussed during the lecture of the OLED display).
The little display we have for the projects has a slightly peculiar connection to the controller chip (ST7735). The ST7735 supports pixel matrixes with up to 132 x 162 pixels (horizontal x vertical). The pixel matrix of our display is only 128x160 pixels large. In principle the controller supports this resulution. In the datasheet in section 6.2 it is explained that the module builder has to put the pins GM0 ... GM2 to b'011' and connect the columns of the pixel matrix to S7...S390 (2 bytes for every pixel with bitfelds for RGB (5bits, 6bits, 5bits) and the rows to G2...G161. However, I believe the configuration pins GM0...GM2 were left at 000, and therefore the chip "thinks" there is a pixel matrix with a format 132 x 162 connected to the chip. This is why the offset of 2 pixels horizontally and 1 pixel vertically has to be adjusted by software with this display.
Fortunately there is a driver (completely written in python) which does this work. It sets all configuration parameters correctly and you do not need to consider any offsets yourself anymore. This micropython driver you can download from github:
https://github.com/boochow/MicroPython-ST7735
To use this driver you will have to look into the source code (not very user friendly... but you will learn something). The following you have to note:
There are different init()
routines included in the driver. This is to make this driver work with modules of different producers. Our module works when calling the initb2() routine. If you call the initr() routine you will have an almost working display. This routine configures the ST7735 chip correctly but it does not consider the offset which we mentioned above. Therefore when you write to the first 2 pixel columns or the first pixel row, you will not see them. And in addtion the last 2 pixel columns and the last pixel row will never be touched by the driver and hence the values of this pixel is a "noise" pattern which cannot get rid of.
The routines implemented by the driver can be lookded at in the ST7725.py file. In addition there is an demo program graphicstest.py
which you can run after you have adjusted the pin numbers and the init routine (change to initb2). And after you have uploaded the used font to the microcontroller. (It is the font called sysfont.py
which can be downloaded from another git repo as stated in the documentation on the git project page. The If this routine runs you have your display working. You can also see quite some functions being used by this demo program.
You can also check out the maximal frequency with which the display can be operated. For me 4 MHz was passible without problems. Going to 8MHz caused problems. Leave some safety margin in your project!
GPS module GY-NEO6MV2
GPS modules are nice gadgets to build remote controlled toys or Trackers. These modules have becaome cheap and extremely easy to use. The complex operations to extract position and time data from weak satellite signals is all handled by the module. (Did you know that the formulas to calculate the location involve general relativity, one of the most complex physics theories by Alber Einstein?) The module itself contains a processor which is programmed by the manufacturer. The interface to the module is, as usual in the microcontroller world, implemented with either a I2C, a SPI or an UART interface. The module we propose to use for projects only supports the UART interface.
The datasheet of the module you can download here:
Even though there are many parts in the datasheet which are hard to understand, if you are (like me) not an GPS-expert it is interesting to read and gives you an idea of the underlying complexity of this module.
Contrary to the complex internals, these modules are very easy to use: they work right out of the box. They constantly spit out GPS data in form of ASCII strings via the UART. These strings can be received via an UART by the microcontroller and the data can be further processed. By default the module sends a set of lines every second.
If you use the module for the first time (a "cold start") it takes a lot of time before the first "fix" (i.e. the position) is established. For me it took many minutes (and not only ~30s as the data sheet claims). The length of this first cold also depends on where you operate the module. If you operate it outside with no trees and building around you the fix will be found faster since more satellite signals will be received. If you operate it inside go to a window from which the sensor can "see" a possibly large fraction of the sky. GPS signals are also influenced by clouds (however, I do not know a method to remove these...).
Once a first fix has been establised, subsequent power cycles will find the GPS location much faster. The module remembers (in a flash) the previous position and this helps when powering on the module and performing a "warm start". (If you do a long journey with the module powered off a new cold-start needs to be performed at the new location)
Fortunately the output of GPS modules have been standardized. The strings being spit out by the module follow either a protocol developed by the company which built the module (ubox) or they follow a standard protocol called NMEA 0183 (version 2.3). These strings are easy to process in a microcontroller. They contains information about the time, the location, the quality of the signal, the satellites found by the module, the position of the modules and more. The module can be configured to determine exactly which NMEA sequences should be output and how often (max 5Hz for our module). But by default once a second all noramlly useful data are sent via the UART.
The format of the NMEA messages is documented in the
If you want to dive deeper into the fascinating world of GPS receivers here you find the manual with the complete receiver description and protocol specification of the module proposed. This allows you also to change the configuration of the module.
Receiver Description for u-blox 6
IMPORTANT NOTE: I recommend to connect the module to the 5V power pin of the ESP32. That voltage comes directly from the USB connector, i.e. from your computer and not from the power regulator of the ESP32 (the ESP32 operates with 3.3V and hence contains a small power regulator on board.) The reason is that the GPS module draws quite a bit of current which might go beyond the limit of the small 3.3V power regulator (in principle the module can also operate with 3.3V power supply). To not overload the power regulator of the ESP module it is better to connect the module directly to the USB power (i.e. to the 5V pin of the ESP module.)
High quality stereo audio DAC
The module GY-PCM5102 is based on a chip of Texas Instrument called PCM5102.
This little module is available on the market for ~1 Euro and produces high quality analogue stereo signals from digital input stream via the I2S interface. The I2S stream is a serial data stream designed to transfer stereo audio data over a serial line. Sampling data are altrenatively transmitted for the left and the right channel. The LRCLK tells the receiving part for which channel the received data is. Further there is a BCK (Bit clock) line which used to synchronise the data transmission. Finally there is the master clock (labelled SCLK in our module) which is high frequency clock synchronous to SCLK and which is used internally but the I2S hardware. However, most (but not all) modules are able to derive this clock with a PLL circuit from the BCK. Our module is on of those and hence we do not need to provide this clock.
It provides a Line out analogue signal meaning that in principle this output is not able to drive a headphone since the connected impedance should be at least 1kOhm. (Headphones usually have impedances of below 100Ohm) However, if you plug a headphone into the output plug the module produces still a very nice sound (probably the values claimed in the data sheet are then not reached, i.e. more distortions are expected...but you need very well trained ears to hear this)
The power supply Vin should be connected to 5V, however, the digital signals are 3.3V level signals (i.e. compatible with our ESP32).
The signal can be fed with 16, 24, or 32 bit audio data! (CD quality is 16 bits.) The I2S master clock does not need to be provided since the module can generate this clock internally with a PLL circuit (see above). For this to function the SCK has to be conneced to ground. Audio signals with sample frequencies of up to 384kHz are supported. There are further inputs
- to fine tune Interpolation filter settings. This influences the roll off behaviour of the filter which is supposed ot filter out the digitization noise. It is questionable if the difference of the setting is audible (also with a very expensive HiFi equipment...) So in short: there is no need to adjust this and we can use the default.
- 44.1kHz De-emphasis control (default: off. There are some rare exotic CDs which are recorded with some emphasis function for high frequencies (to reduce noise) and these CDs have to be played back with de-emphasis being switched on to have the high frequency content not over-emphasised which would sound very bad...)
- to select the Audio format (I2s or "left justified". Defaiult is I2S which we are using with the ESP32.
These options are only selectable if you remove the solder bridges on the back of the module. The defaults set with these bridges are good for 99,99% of the use cases and good for all our use cases in this course. Therefore the pins header has not been soldered on the board for these pins (it would be anyway in a awkward position at a 90 degree angle to the main pins, which would be incompatble for using this module on a breadboard.)
Final remark: make sure you plug your headphone completely into the (somewhat fragile) audio connector, otherwise you will only hear a mono signal.