====== Getting Started With Controllers ====== Version 1 - 01.2024 ===== Introduction ===== When choosing the brains of projects, a lot of options are available and sometimes a combination of multiple. These brains are also called Micro Controllers (and raspberry pi), these controllers read the sensors, command the actuators and send the data around. For some more in-depth overview of specific components or examples, you can also go to edwin dertiens site. To get the login you can mail [[d.p.davison@utwente.nl| Daniel Davison]]. For an introduction on working with electronics components you can also look at [[https://github.com/utwente-interaction-lab/interaction-lab/wiki/Getting-started-with-Electronics| Getting started with Electronics]]. ===== What Controllers are there? ===== There are multiple types of controllers, the biggest division is the raspberry pi and the actual microcontrollers. The raspberry pi runs on an operating system and is basically a small computer but does have the ability to read sensors and control actuators with its GPIO header. But since the pi does a lot of other stuff it is not always the best option for time-critical things. Below is an overview of the most commonly used controllers with their pros and cons. ==== Single Board Computer - SBC - Raspberry pi ==== There are a few raspberry pi’s available but the most common ones are the pi 3, pi 4 and pi zero (w). The pi zero and pi zero w are a pi one in a small package, it is way less powerful than the other two pi’s but also uses less power. None of the pi’ should be used to operate for a week on a battery since they need too much power for that, but a day is possible. Since the pi runs a version of Linux it can be used for running more intense applications like machine learning or running web clients. The pi can communicate with digital sensors but needs a shield or external board to work with analogue sensors. All pi’ except the pi zero non-w have Bluetooth and internet capabilities. The pi zero non-w can do this with the use of a WiFi dongle. Recently there also has been a Raspberry pi zero 2 W released by the pi foundation. This is the SoC (System on a chip) from the raspberry pi 3 with less ram and a lower CPU speed but in the form factor of the raspberry pi zero. The power consumption is somewhere between the 3 and original zero. ==== Microcontrollers ==== Microcontrollers are different from single-board computers like the raspberry pi since they do not run a real operating system. You compile the code that runs the specific tasks you tell it to do. Meaning no other programs are in the way when a sensor has to be read when you do not want it to or that it starts updating itself. This is more efficient meaning that the simple tasks can be executed without using a lot of power. === Arduino UNO - ATmega328 === The most basic microcontroller is the ATmega328 and all controllers that use that chip like the [[https://store.arduino.cc/products/arduino-uno-rev3 | Arduino UNO]] and [[https://store.arduino.cc/products/arduino-nano | Nano]] (non 33). This controller is enough if you want to read some basic sensors or control some actuators. You can interact with it over the serial port of your computer (USB) or with the use of a shield uses it over the internet. === Arduino Mega === If a project requires a lot of general-purpose input-output (gpio) pins you might need the [[https://store.arduino.cc/products/arduino-mega-2560-rev3 | Arduino Mega]], which has 54 pins compared to the Uno's 14. This one is based on the ATmega2560 chip. It is not much more powerful or modern, only more useful due to its pins. Besides having the extra basic pins there are also more with PWM and more serial outputs. === Arduino Nano 33 === [[https://store.arduino.cc/products/arduino-nano-33-iot?selectedStore=eu | Arduino Nano 33]] is a new range made by Arduino of small controllers with a newer chip design. These are more efficient and powerful than the ATmega328. They also come with a range of connectivity options already built-in like WiFi, Bluetooth or LoRa. They are a bit more expensive when compared to an older Arduino clone from Aliexpress and also may be harder to borrow. But when you have a project where things have to communicate over distance, having the convenience of easy WiFi integration makes work easier. === Espressif esp32 === The [[https://www.espressif.com/en/products/socs/esp32 | esp32]] is a powerful cheap chip originally made by espressif, but the chip has been used in many development boards that can be bought cheaply from aliexpress, but also if you want some more certainty about the quality from [[https://www.adafruit.com/product/3405 | adafruit]]. The big advantage it has over the other controllers is that it has built-in WiFi and Bluetooth. It is also way more powerful since it has dual-core capabilities, which by default is used to separate connectivity tasks from the main code you write yourself. Since there are many different development boards made from the esp32 there almost always is a board that fits your specific needs. Some examples of boards once with LoRaWAN builtin or an OLED screen. ===== Programming languages for microcontrollers ===== When programming for microcontrollers (Not Pi’s) there are currently two options available; c based and python based. The options for raspberry pi or discussed after that. ==== Arduino/platformIO (C) ==== The ArduinoIDE programming is based on c but made a bit easier. The arduinoIDE is easy to use and handy for smaller projects. It did miss some features but most have been solved with the Arduino pro IDE which adds things like text completion. When doing bigger projects using platformIO which can be added in IDE’s like visual studio is the better choice. A big advantage is that libraries used are put in a file, meaning that when someone else opens the project all the correct libraries will be downloaded when compiling the code. This can be useful when only a certain version works or when for example a neopixel library is used since there are many available. Support for controllers and libraries is the same since in the background platformIO still uses Arduino for these kinds of things. Since Arduino has been the standard for years nearly all libraries and controllers support the arduinoIDE and platformIO. ==== Micropython/Circuitpython(Python) ==== Circuitpython is a version of micropython but made a bit easier and maintained by adafruit. Since adafruit is also the manufacturer of most digital components like neopixel, almost all libraries that are used are available for micropython/circuitpyton. However, it is newer than Arduino meaning the availability of libraries is less extensive. The same goes for controller support, the older Arduino’s do not support micropython/circuitpython. But a big advantage is that the code is stored on the controller and accessible from the controller via USB. This means that you don't have to transfer code around when doing small changes. It is just like regular python, an interpreted language, meaning you can program it live. You can type to the controller to turn a pin on and it will be done immediately without having to recompile the code. There are some IDE’s available but it can also be done with a program like putty and notepad since the compiling is also done on the controller itself. This all does give some extra overhead and less efficient compiled code, but this is not noticeable. ==== Raspberry pi ==== Since the raspberry pi is a computer you can program it to do things in any language you want, but also download programs from the internet. Do make sure it is compatible with the raspberry pi since the CPU is arm based and not x86 (normal computers). To install an operating system to the raspberry pi you need to flash an ISO to a micro sd card which is explained [[https://www.raspberrypi.com/software/ | here]]. There are two types of operating systems that can be installed on the pi; headless or with a desktop environment. Headless means that only a command line is available, which might be a bit more difficult if you are not used to it. The other option is just like normal windows or macOS meaning you need a screen, keyboard and mouse to control things. However, running a desktop environment does use some compute power and is usually not needed if you run it as a server or microcontroller. ===== Communication with controllers ===== There are a lot of ways to communicate with the controllers to get the data or tell them to do something. Depending on how they are used this might be something to take in mind when choosing a controller. ==== Serial ==== The most basic type of communication is serial, this is what you almost always use when uploading new code, and is also used for Serial.print statements when debugging or testing. However, this is only useful when the controller can stay near your computer/laptop or maybe raspberry pi. To automate commands or use the data a different program is needed since the Arduino IDE is not meant for this. This can for example be done with processing or python. But almost all programming languages have libraries available to work with USB devices connected to the computer. Serial might not be the best option when you have controllers distributed all over the place. Since you need a wire to be connected, powering is quite easy since this can be done via the USB cable connected to the computer. Serial is not a valid option for flashing new firmware to raspberry pi like it is with a microcontroller. With the use of a UART to serial board, it can be possible to read out values from a pi, but this is quite unusual. ==== WiFi ==== Another easy way to communicate with your controller is WiFi, a disadvantage is that you need some extra infrastructure. For example, connecting the controller with WiFi capabilities on eduroam is not possible. Meaning that you need to set up a cheap router to do the networking and connecting for you. Also when choosing WiFi you need to choose a protocol to communicate with, some of the options are TCP/IP and MQTT. When keeping everything on the same network it is usually not needed to configure ports. It can be handy to give devices a static IP address so they can be hardcoded. If you want to access devices on the router you need to connect the router to the internet (WiFi and internet are not the same things). By default, all ports are closed and inaccessible from the outside, but routers can forward certain ports to devices it is necessary. But be careful since it can be accessed by everyone, make sure things of some type of password protection. ==== TCP/IP ==== TCP/IP is a protocol that works directly from device to device and can work with every device that has internet capabilities. Just like with serial communication all programming languages have libraries that support this way of communication. ==== MQTT ==== MQTT is a protocol that makes use of a broker. It works with subscribing or publishing to topics. The clients connect to the broker which can run on a computer or raspberry pi on the same network. And every client either publishes (sends data) to a topic or subscribes (receives data) to a topic. The advantage is that it is possible for multiple clients to receive data from a device and you can retain states meaning that devices did not have to be on when data was sent. ==== NodeRed ==== An easy way of connecting to both MQTT and TCP devices is with the use of NodeRed. Especially when you use MQTT since you already have a computer running the broker. It makes putting data in for example in a database fairly easy. ==== SSH ==== SSH is a protocol that enables you to control a raspberry pi or server (also a normal computer) over the internet. This usually works on port 22 (when port forwarding this make sure you do not have an easy or default password). You can run ssh from almost any computer and gives you a command-line interface to do things on the other computer. This is handy when you need to run programs from a distance on a raspberry pi and do not have any peripherals connected to it. It is necessary to enable it on a computer since it is usually disabled by default for safety reasons. To enable it on the pi you can look at [[https://roboticsbackend.com/enable-ssh-on-raspberry-pi-raspbian/ | this tutorial]]. ==== Bluetooth ==== Bluetooth can be useful when the device needs to be wireless and is not in a set location. So for example a wearable device for running. Since WiFi is not always available and communication directly to a device like a phone works better with Bluetooth. Another advantage is that Bluetooth can be very low-power which makes it more suited for battery-powered devices when compared to WiFi. ==== LoRaWAN ==== When you need a device that needs to communicate over a long distance without using a lot of power, LoRaWAN is the best option. When making a sensor node that needs to be deployed without a power supply for a month somewhere in the field for example. But LoRaWAN communicates over its own frequency band with its own protocol, meaning that you need to have a LoRaWAN gateway to be able to receive the data. This receives the data from the controller and can make it internet accessible. If you are lucky you can use [[https://www.thethingsnetwork.org/ | the things network]] for this, here people can deploy gateways and make them accessible to other people. ===== Communication with sensors ===== When working with digital sensors (meaning not analogue or not building the whole circuit) there are a few standards used between sensors and controller. The most common will be discussed below and they are all digital in nature (communication with 0 or 1). ==== UART - (Universal Asynchronous Receiver-Transmitter) ==== UART is related to the normal USB port but is a bit lower level. The communication works both ways and most controllers have pins that support this protocol. These pins are labelled Tx and Rx but do make sure the controller can use these for external sensors since the communication for uploading code also uses UART pins on most controllers. When connecting to the sensors 4 pins are needed, the discussed Tx and Rx pins but also ground and 5V. Ground and 5V from the controller go to the 5V and ground of the sensor, but the other two have to be crossed (Tx -> Rx and Rx -> Tx) since T sends for Transmission and R for Receiving. In code, the right bitrate has to be set since there are multiple standards but the most common ones are 115200 and 9600. If the bitrate of the controller and sensor do not match both sides can not understand each other. UART can be used to have communication between controllers and some more industrial or older sensors use it. [[https://www.circuitbasics.com/how-to-set-up-uart-communication-for-arduino/ | Here]] is an example of UART communication between controllers. ==== I2C (Inter-Integrated Circuit) ==== I2C is a protocol used by newer digital sensors and can be used for slow short-distance communication. Just like with UART it used 4 pins: * Power (3.3V/5V) * Ground * SDA (Serial data) * SCL (Serial Clock) With these 4 pins, multiple sensors can be connected since the protocol is a bus where every sensor has its own address. Meaning on the same 4 pins a temperature sensor and an OLED screen can be controlled. But connecting two of the exact same sensors is usually not possible. Almost all sensors that adafruit makes use I2C like for example this temperature sensor ==== SPI - (Serial Peripheral Interface) ==== SPI is related to I2C since it is a bus type interface so multiple sensors can be connected to the same pins. But instead of two wires for communication four are needed and a higher transfer speed. This is useful with sensors that can read data very fast or multiple faster sensors are on the same bus. The six pins used for SPI are; * Ground * Power (5V/3.3V) * SCLK (Serial Clock) * MOSI (Master Out Slave In) - data output from master (Microcontroller) * MISO (Master In Slave Out) - data output from slave (Sensor) * CS/SS (Chip/Slave select) - Indicates that data is received by the master to the slave In practice, a lot of sensors that support SPI also support I2C an example of an SPI sensor and how to wire it is can be found [[https://www.arduino.cc/en/Tutorial/LibraryExamples/BarometricPressureSensor | here]]. ===== Types of pins ===== ==== Analog ==== There are two types of analogue pins; Analog in (ADC) and Analog out (DAC). The first one is present on nearly all microcontrollers and stands for Analog to Digital Converter. These pins can translate an analogue signal to a digital value within a certain range. This pin is useful when having to measure circuits built from the ground up like for example measuring the battery voltage with a voltage divider circuit. But also sliders or potentiometers as input to the controller. The second pin type (DAC) can transfer a digital value to an analogue value within a certain range as output; these can be useful in audio applications. ==== Digital ==== All pins accessible on a microcontroller can support digital functions of which the most basic is reading high or low usually above or under half of the io voltage value. (2.5V for 5V and 1.6 for 3.3V). However, not all pins support all protocols from the list above or PWM. What each pin supports can usually easily be found when googling pinout + the name of the controller. Also, all communication standards discussed above use digital pins, but not all digital pins can always be used for all these standards. That is why it is best to look for a pinout diagram of the controller u use. ==== PWM - Pulse Width Modulation ==== Pulse width modulation basically means the ability to switch pins on and off real fast and vary how long they are on or off. When using this you can dim LED’s for example since the LEDs are on for less time depending on the value. But this is so fast you can not see it flicker. A more detailed explanation can be found [[https://en.wikipedia.org/wiki/Pulse-width_modulation | here]]. When combining this with a [[https://www.allaboutcircuits.com/technical-articles/low-pass-filter-a-pwm-signal-into-an-analog-voltage/ | lowpass filter circuit]] to change a voltage level, but this is a bit more advanced. ===== Pitfalls ===== When working with the more basic components especially higher power components there are some things to keep in mind. Some of the more common pitfalls will be discussed below. ==== Powering from Battery ==== Sometimes it is necessary to power the microcontroller on their own without power available in the area. For those cases, they can run on a battery since it uses little power. However, it can be difficult to use a power bank since some power banks stop charging if there's almost no power taken. Since an Arduino uses less than 100mA compared to more than 1000mA a phone uses while charging. This is often triggered when powering a microcontroller with a power bank. Finding out which power bank does this can be difficult. Some cheaper ones might not have this mechanism and some more modern ones sometimes have a feature to disable this. But another option is to use a Li-ion battery or some normal batteries. Some controllers have a special connector that excepts a battery and even allows it to charge. In other cases, a special circuit can be used like this [[https://www.tinytronics.nl/shop/en/power/bms-and-chargers/li-ion-and-li-po/without-protection-circuit/tp4056-mini-usb-li-ion-charger-1a | TP4056]]. It does require some soldering but it is fairly simple. When normal batteries are used a boost or buck converter has to be used to make sure the correct input voltage is maintained. A boost converter boosts the voltage and a buck converter lowers it, to lower the voltage a linear voltage regulator can also be used. Just make sure to check the input voltage of the controller (most have a 5V port with their own regulator) and the voltage of the battery setup. If the controller is used to measure a few times per hour the deep sleep function can be used. Most controllers support this and it puts a controller in a low-power state where it barely uses power. It can wake from a timer set in code, but also with a button press for example. ==== Separate power applications ==== When working with components that require more than 5v or 100mA (for example motors, led strips) the use of transistors, MOSFETS or relays is needed. These components can be told to turn on or off with a digital signal from the microcontroller but can be put in the line of an external power supply. MOSFET and transistors can only be used for DC or direct current (what comes out of a power supply), but can switch very fast (1000 times per second or more). For AC or alternating current applications, they can not be used. Here a relay can be used but it can turn on or off maybe one time per second. A relay can also be for DC applications or basic in principle since it is mechanical (magnet that opens and closes a switch). ==== Avoid delay ==== When code is simple delay can be an easy way of for example making an LED blink. But the use of delay stops the entire code, meaning that other applications that have to keep doing their thing will also not be executed. This is why you code functions that have to be done once per second instead of as many times as the controller can handle in an if statement with millis(). The function millis() tells how long the controller has been running so variables can be compared against it. Like for example in the code (arduino/c) snippet below; Long previousMillis = 0; // variable to store previous running time Long interval = 1000 // how many milliseconds the function has to wait before running again Void setup(){ Serial.begin(115200); } Void loop(){ Long currentMillis = millis(); // stores current running time // if previous function activation has been longer than the time set with the interval execute the function. If (currentMillis - previousmillis > interval){ Serial.println(“Hello”); // prints Hello previousMillis = currentMillis; // reset the variable currentMillis to current run time. } }