Probably some of you are struggling in finding a proper LCD driver that would work on any circuit. Just wanted to point out that I found some time to improve my current LCD library so it would support a mixed pin connection case. Earlier you had to connect LCD in a pretty strict way where pins had to be aligned and attached to single AVR port. Sometimes this can’t be done due to various reasons – you want to use those pins for other alternative functions, or you want to trace your PCB better, etc. In this updated version of library there are two more modes added: LCD_4BIT_M and LCD_8BIT_M that allow controlling LCDs either in 4 or 8-bit mode but with any pin connection layout. So data pins and control pins can be connected to any PIN and any port. Couple examples should give some clue on how to start using it. If you used this library for some project, you only need to modify header file while project source code can remain the same. Download LCD library here.
AVR microcontrollers aren’t the best choice to run FreeRTOS scheduler due to low on-chip RAM. Atmega128 has only 4K of RAM, so this limits the FreeRTOS functionality to very basic. Anyway, this problem can be solved by adding extra RAM which may be connected to an external memory interface. We have already built an external memory block of 8K previously so now we can test it with FreeRTOS applications. Lets continue with our previous code which runs several simple tasks (button state reading, LCD output and LED flash), and we can add more to it. We are going to set up an external RAM for storing heaps. This will allow to store large data buffers without worrying too much about heap and stack overlaps.
In the previous post, we just run a single task. Running RTOS with single task has no meaning at all. This can be quickly done with a conventional program. But what if we need to have more separate functions. To execute them at exact timing would require a separate timer or interrupt. But microcontroller cannot guarantee an interrupt for every task. This way it is hard to make code modular, and testing can be painful. Using RTOS solves this kind of problem. It allows programming each task as an endless loop. Kernel scheduler takes care of assuring each task gets its chunk of processing time. Additionally, it does bearing the priority systems – more critical tasks are executed before less important ones. Let us go further with our example code and add more tasks to our FreeRTOS engine. We already have LED flashing task that toggles LED every second. Additionally, we are going to create another task that checks the button state. Also, we are going to send some information to the LCD. As always let’s take care of drivers for all of them.
FreeRTOS is known as Real-Time Operating System. Probably it would be too dare call it real-time-os, preferably a real-time scheduler where applications can be split into independent tasks that share full processor resources by switching them rapidly it looks like all functions are executed in parallel. This feature is called multitasking. There are lots of debates on using RTOS on AVR microcontrollers as they are arguably too small for the running scheduler. The main limitation is a small amount of ram and increased power usage. If you are going to use lots of tasks in the application, probably you will run out of RAM that is used for saving context when switching between tasks. Consider FreeRTOS only if you use larger scale AVRs like Atmega128 or Atmega256. Surely you can find smaller schedulers that are specially designed for smaller microcontrollers even tiny series. In another hand, if you master FreeRTOS, it can be used with multiple types of microcontrollers like ARM, Cortex, PIC and various compilers including IAR, GCC, Keil, Rowley, Attolic. And the main reason to keep an eye on it – it is free. Probably it would take lots of time and space to go through RTOS theory.…
Servo motors are so-called “closed feedback” systems. This means that motor comes with a control circuit inside, which senses if the motor mechanism is in the desired position, and if not, it continuously corrects an error until the motor reaches the angle. Servo motors are widely used in robotics, remote-controlled planes, vehicles, and many other industrial machines. They come in many shapes and sizes, but they all operate in almost the same way. Usually, servo motors are controlled by computer, microcontroller or even simple timer circuit. How Servo Motor Control Works Usually, servo motors are put in the plastic box, but inside there is a whole system: motor itself, gears and motor driving and control circuit. The gears reduce motor speed but increase torque. As we mentioned, servos work with closed feedback loop when the potentiometer is connected to a mechanical shaft and senses the angle of turn. The potentiometer voltage directly indicates the angle of twist. Potentiometer signal goes to a digital controller of the motor which powers motor until potentiometer reaches the desired angle, then logic circuit shuts the motor.
Let us write a simple LCD menu for AVR. I am using four buttons: 2 for menu scrolling up and down and two for changing submenu parameters. As the output indicator, I am using three LEDs that flash according to parameters selected in the menu. Button states are captured by using timer0 overflow interrupts. The circuit is elementary: have excluded power circuit for simplicity, just left main parts: LCD, LEDs, and buttons. This circuit works well with Proteus simulator as it is. Proteus circuit is attached to the project archive. My idea is to store menu strings in Flash memory without occupying MCU RAM. This way, menu items are limited only by Flash memory, not by RAM.
Earlier I have used 4-bit and 8-bit LCD libraries in different projects. It was hard to maintain and update. Now they are merged in to one library where the simple logic structure is implemented to select 4-bit or 8-bit LCD library just by modifying only three lines of code. In the library header file there is line added: //Uncomment this is LCD 4 bit interface isused //****************************************** #define LCD_4bit //****************************************** You can select different LCD modes by commenting and uncommenting this line. Also, don’t forget to select proper ports and pins where LCD is connected: #define LCD_RS 0 //define MCU pin connected to LCD RS #define LCD_RW 1 //define MCU pin connected to LCD R/W #define LCD_E 2 //define MCU pin connected to LCD E #define LCD_D0 0 //define MCU pin connected to LCD D0 #define LCD_D1 1 //define MCU pin connected to LCD D1 #define LCD_D2 2 //define MCU pin connected to LCD D1 #define LCD_D3 3 //define MCU pin connected to LCD D2 #define LCD_D4 4 //define MCU pin connected to LCD D3 #define LCD_D5 5 //define MCU pin connected to LCD D4 #define LCD_D6 6 //define MCU pin connected to LCD D5 #define LCD_D7 7 …