Thursday, 9 February 2017

mbed RTOS - Roborealm, Joystick, and Servo Pan & Tilt - Thomas Murphy


An RTOS program was written to control servos for pan and tilt using a joystick. This was done using threads, memory pools and queues. Another thread is used to read in values serially which are being sent from Roborealm. Depending on the value received from Roborealm, an LED is turned on or off.

Using Roborealm

Thanks to a great Roborealm basics run through from Sophie, the following information was found. Robrealm's object recognition was used to scan for a particular shape and send a message with a value based on whether the object is detected or not. The image of a swirl was trained into Roborealm and when detected the variable count is set to 1, otherwise it is 0. The picture below shows how the count value is 1 when the swirl is detected. The count is set based on the OBJECT_COUNT variable which is available when the object recognition module is used.

The Serial module is then set up to send values serially to the mbed. The port has to be changed to target the mbed and the baud rate must be adjusted to allow for serial communication with the mbed. Placing something inside the send sequence box will send it serially and putting it in square brackets will send down the value in a variable with that name. The picture below shows the serial communication and the 1's and 0's being transmitted serially.

mbed Code Explanation

The code starts with all the definitions, includes, etc. that are needed and then two message structures were written, one for each servo. This was done as I wanted to use two different threads to control the servos so using different messages allowed this, especially since a message read is destructive. Two memory pools and queues were set up for the same reason. The char c is used when reading values from Roborealm and is declared as a variable. This was purely for comparison with the passing of values using memory pools and queues. A value should essentially never be declared globally in a RTOS because it could so easily cause race hazards. In this case, the character from "c" is only using in one thread so it will not cause a race hazard.

The first thread is main() where the integers pan_degree and tilt_degree which will be used to control the servos. They are declared locally instead of globally to avoid race hazards mentioned above. main() reads the joystick on the development board and based on its position and the pan_degree or tilt_degree angle, the value of pan_degree or tilt_degree is incremented or decremented by 5. So if the joystick is pushed right and pan_degree is less than 170 then the pan_degree value is incremented. This value 170 is to make sure the servo will not be sent to an angle it can't reach. It can go to 180º but due to issues noticed where the motor was struggling to get to exactly 180º, the permitted range was lowered to 170º hence 170 integer value. The other if statements work in the same way. Once the new pan_degree or tilt_degree value is set it needs to be loaded into the memory pool so it can be used by its corresponding servo control thread. So the address to a free slot in the memory pool is loaded into a pointer. Using this pointer, the pan_degree value or tilt_degree value (depending on which if statement is running) is loaded into the memory pool. The address for this location in the memory pool is loaded into the corresponding queue for the servo. This thread now finishes and asks to be removed from the processor for 100ms.

The next thread which runs reads messages which have been sent serially to the mbed from Roborealm. The thread checks for a character on serial and reads it into the variable "c". If the character is a '1' then led1 is turned on or if it is '0' led1 is turned off. Either way the LED is either turned on or off every 500ms based on the duration of the Thread::wait().

The next two threads are for controlling the servos and work in the same manner but access their corresponding queues and memory pools. The thread starts by checking its queue for any new addresses. If there is a new address then it is read in. This address is used to point to the location of a message for the servo waiting in the memory pool. The message is read and the servo angle is written to the servo. The memory pool location is then freed for another message and the thread ends.

Remember: The memory pools and queues are needed to allow for IPC (inter-process communication) i.e. to allow values to be passed from one thread to another.

The full mbed program discussed in this blog is below.

This video shows the program operating.

About Me

My name is Thomas Murphy and I'm studying the BSc in Applied Electronic and am in the final semester of my final year. I have enjoyed working with circuits through my technology class in secondary school. My technology teacher suggested that I look into electronic engineering courses and here I am five years later. Electronics was definitely the best course choice for me and I love working with hardware and software and still smile when I toggle an LED. My third year project working on BENGiE was my favourite project to date and my placement in Analog Devices showed me just how much I enjoy working as an Electronic Engineer. I have high hopes for the Lampbot project and am looking forward to seeing what my class and I can achieve as a group.

In my spare time I enjoy working on my family farm because it gets me out of the house and doing something different. Working with animals is something I think everyone should experience. I also really enjoy golfing and try to go whenever there is a break in the weather.

Technical Interests
I have always enjoyed farming and have always been keen on trying to improve farming using any electronics knowledge I have gained over my course. Considering this it only made sense that my final year project would have something to do with farming. Looking at my own farming experience I decided that I am going to try improve the efficiency of the lamb weighing process.

Life Mottos
Enjoy the little things!
Give credit where credit is due.

No comments:

Post a Comment