﻿ Week 15 - Scott Zitek - Fab Academy 2014

# Scott Zitek - Fab Academy 2014

## Interface and application programming

### Week 15 Assignment

The assignment for this week is to write an application that interfaces with an input and/or output device.

### Application

I decided to make an interface to help with the programming of the RC servo positions for my final project. To position the RC servos you program a value that defines the position that you want. Unfortunately, this value is not in degrees. It is based upon controlling a pulse typically between 1 and 2 milliseconds long. With hardware PWM (pulse width modulation) control there is an equation in the data sheet that can be used determine the result of a value.

The PWM frequency for the output when using phase and frequency correct PWM can be calculated with this equation.

In my application:

• fclk_I/O = 20,000,000 (20 Mhz)
• N = 8 (my prescaler divider)
• TOP = the value you enter. For example:
• To set the overall frequency of the pulses ICR1 = 25000. So with TOP = 25000, the equation works out to 50 Hz. So 1/50Hz = 20 ms.
• To set the length of the control pulse for the servo connected to ATTiny 44 pin 7, OCR1A is set for a value like 1875. Which the equation indicates will be a 1.5 ms pulse. This should be the middle position of the servo.
• To set the length of the control pulse for the servo connected to ATTiny 44 pin 8, OCR1B is set for a value like 1250. Which the equation indicates will be a 1.0 ms pulse. This should be the CCW position of the servo.

This equation however only determines the resulting PWM signal not the position of the RC servo motor. To make things more interesting, how you attach the horn to the servo defines your starting angle. Servos also vary in range of motion and how far they move for a given pulse width modulation signal.

For my electro-mechanical scoreboard project, I need to know the values for 28 different servo positions. I can determine these position values by trail and error but it is very inefficient and time consuming.

### Microcontroller program

I modified my ATTiny 44 program to manually jog the servo motors by increasing/decreasing the OCR1A and OCR1B values that control the hardware PWM to the servos.

• Upon power up both OCR1A and OCR1B are set for 1875 which should be the center position for both servos. This is useful for installing the horn on the servo in the correct position.
• Pressing the UP button increases the OCR1A and OCR1B causing the servo motor to move in one direction.
• Pressing the DOWN button decreases the OCR1A and OCR1B causing the servo motor to move in the other direction.
• If neither button is pressed, it holds the servo positions.
• If both buttons are pressed at the same time, OCR1A and OCR1B are reset to 1875 which should be the center position for both servos.

I also added the programming needed to take the current PWM value and Hz_pulse value and send them via an asynchronous serial bus to a PC.

I wanted to send both the hardware and the software pwm values since they are different. Unfortunately, I was not able to modify my program to variably control the software PWM value on-the-fly. For some reason the delay.h library wants a constant for each delay defined when the program is compiled. I modified my program to run a loop that calls up a variable delay but for some reason it did not work. The software PWM controlled servos would move to the end of travel upon power-up when the value was set for the center position. I suspect this was caused by the additional overhead time of executing my approach or the way I stored my values in memory. In the interest of time management, I decided to concentrate on the hardware PWM for this assignment. Instead of sending the software PWM value I calculated the pulse_hz value and sent it. This was unnecessary since I could have also calculated this value on the PC side.

### The Communications Interface

When I designed the circuit board for controlling my electro-mechanical scoreboard, I added a communication port for the asynchronous serial bus. I figured I could use it to optionally add wireless control of the scoreboard and/or if I wanted to take a modular systems approach. I used this interface to communicate with a PC. However, this board only had bus the connector of a "node". This network also typically needs a bridge circuit that also has a FTDI (USB-to-serial) connector on it. Since I didn't need to communicate to anything but a PC, I decided to make a simple FTDI to 4-pin asynchronous serial bus adapter cable. This adapter cable might also come in handy when initially programming individual nodes to go on an asynchronous serial bus network.

A simple FTDI to 4-pin asynchronous serial bus adapter cable. It may not look real pretty or be durable but it works. I didn't have heat shrink tubing so I used liquid electrical tape. I didn't have a 4-pin ribbon connector socket so I used a 6-pin. Consider this a successful prototype.

In addition to communications, the FTDI/4-pin bus cable also supplies DC power from the USB port. Be sure not to use the external controller battery when connected to the asynchronous serial bus

The simple FTDI to 4-pin asynchronous serial bus adapter cable connected to the servo control board. Notice that the battery should be disconnected since power is supplied via the bus connection.

### User Interface

I developed the graphical user interface (GUI) for the PC with Python and Tkinter. This GUI program receives info via FTDI from a hardware PWM servo control board and displays the information on a PC.

For this application I didn't need any moving bar graphs or fancy animations. I just wanted to display the hardware PWM information close to real time and so it look nice.

The graphical user interface showing the needed information.

Since the text and other graphics are positioned and sized based upon the window size, it can easily be scaled by changing the WINDOW value in the Python program for easier viewing and/or different resolution monitors.

I am used to developing human machine interfaces (HMI) for industrial control applications. I typically do this with a very WYSIWYG graphical software. Programming with Python and Tkinter was very different from this. There is plenty of information on the web about making graphical user interfaces using Python and Tkinter. However, for some reason I found it hard at time to find the details I was looking for. For example, what are my options for formatting a value in something like canvas.itemconfigure("text4",text="%.2f"%hardpwm_value). Luckily, it was intuitive enough that I was just able to figure it out. Another thing I questioned was how the program declares data types (e.g. integers vs. floating point). I found that period = (1000/hz_value) resulted in integer answers while period = (1000.000/hz_value) resulted in a fractional answer.

Here is a video of the finished graphical user interface in action. It works very well. The display is very easy to read and "rock-solid" - the values do not fluctuate randomly. It is also very responsive and updates quickly as the servo physically moves.

Click this link if embedded video is not working

Back to index