Skip to content

11. Output devices

  • Add an output device to a microcontroller board you’ve designed and program it to do something.

For this week I decided to design the board for my final project. With the help of Antonio, our FABolous instructor, I managed to design it.

Since I wanted to use this week’s assignment to understand better my final project, I decided to design a board with four servo motors. My final project, indeed, will involve many servo motors and I need to start playing with them in order to be able to do what I have in mind.

πŸ‘©πŸ½β€πŸ³ EAGLE

This board will include an ATmega328, four servo motors and two leds. Here is the pinout of the ATmega328.

ATmega328

This however was not the shape of my atmega328, so I also used this pinout to have a better visual representation of my board.

ATmega328

You can see in the pinout that the ATmega328 has enough PWM pins, which I needed in order to connect the servo motors. PWM pins (in the pinouts are called TIMER/PWM) stand for Pulse Width Modulation pins. They are pins that have the ability to getting analog results with digital means. Digital control is used to create a square wave, a signal switched between on and off. This on-off pattern can simulate voltages in between full on (5 Volts) and off (0 Volts) by changing the portion of the time the signal spends on versus the time that the signal spends off. The duration of β€œon time” is called the pulse width. To get varying analog values, you change or modulate, that pulse width. If you repeat this on-off pattern fast enough, the result is as if the signal is a steady voltage between 0 and 5v controlling the speed of the motor.

πŸ‘©πŸ½β€πŸ³ SCHEMATIC

I started directly to do the schematic by adding the atmega328, whose correct format is UC_ATMEGA88-THIN. Following this step, I added the ISP (named CONN_03X2_AVRISPMD) and a cristal (XTAL_CRISTAL_SMD). I directly connected these components to the attiny looking at the pinout, therefore I connected the cristal to pins PB6 and PB7 since they are XTAL1 and XTAL2. As far as ISP is concerned, I connected the MOSI, the MISO, the SCK and the RESET pins of the ISP to the directly correlated in the ATmega328. I also put a capacitor of 1uF and a pullup resistance of 10K ohm connected to the reset pin.

schematic

For the servo motors I added 3 pads each: 1 pad for VCC, one pad for GND and one pad for the control pin after looking for the servo pinout.

Servo pinout

I added also a LED that lights up when the board is connected, just to check everything works fine. To that LED I connected a 200ohm resistor. I also added a led that can be controlled by the atmega328: I attached it to the PB2 pin, indeed, while the first led is only attached to VCC and GND.

schematic

Eventually, this is the final schematic:

Schematic

πŸ‘©πŸ½β€πŸ³ BOARD

I switched to the board file in eagle and I started to arrange the components in the space. I tried with an autoroute first (with auto command) but I could get only 88% routes. So I started to arrange in the space the components again, trying to find a solution without usign 0ohm resistors but in the end I decided to use one (which you can see in the schematic above). I then changed layer (in the top left corner there is the layer panel) and selected the 20 Dimension layer, which is the yellow one. I wrote line in the command bar and drew a line as a border for my board. Here is the board with the routes (with 0.5mm Clearance and 16mil width in the Design Rules).

board

I went to the layers panel and selected all the layers (with Command+A) and then Hid them all. Then I clicked on Top, Pad and Dimensions to show only these layers for export matters. Lastly, I zoomed out and selected the yellow rectangle that made my black background and deleted it because if you don’t delete it, then you will export the whole rectangle and not only the board.

I then went to File > Export > Image and I browsed to my folder to save the image. I selected monochrome and set the dpi to be 1000. I saved the image that is this:

board

🫐 FabModules

Before going in fab modules, I opened the png in Photoshop and separated the traces from the outline.

I checked that the dimensions of the image were correct since EAGLE has a bug with MacOS and exports the image at the double of the size.

I then did the same process I explained before here and started milling as explained here. I soldered the board and here is the final result:

result

πŸͺ Arduino IDE

In order to program my board, I needed to prepare the pipe.

I proceeded opening arduino ide and added the board processor for ATTINY. I did so by opening the preferences in Arduino IDE

preferences

and clicked on Additional Boards Manager URLs.

Additional Boards Manager URLs

I then pasted the following url.

https://mcudude.github.io/MiniCore/package_MCUdude_MiniCore_index.json

Url pasted

I then could open the board manager that you can find in Tools > Board > Board Manager (or using the shortcut SHIFT+COMMAND+B in MacOS)

board manager

and clicked on INSTALL.

Installed

Now that I have the board installed, I can select it in BOARD as follows:

board selected

And eveything is ready to be moved!

🏷️ The code

I wrote a very simple code that made the servo motor move accordigly to the potentiometer. Let’s disclose it for the newbies, like me.

πŸŽ€ Declaring my variables

First off, I have to declare my variables. In this case, I declared the pin for the servo and the pin for the potentiometer. I looked at the pinout, of course, to see which pin was what. I then declared an int variable named val for the angle of my potentiomenter.

int servoPin = 8; 
int potPin = 7;  
int val;   

πŸ“ͺ Setup

In the setup part, I attached both the servo and the potentiometer to their relative pins with pinMode and of course I set the servo as an OUTPUT and the potentiometer as an INPUT.

void setup() {
  pinMode(servoPin, OUTPUT);
  pinMode(potPin, INPUT);
}

πŸ₯¨ Loop cycle

In the loop cycle, I first of all assigned the val variable to an analogRead of the potentiometer in order to see the value of my potentiometer.

val = analogRead(potPin);

Then I used the map function to convert the values of the potentiometer, that go from 0 to 1023, in an angle from 0 to 180. The map function re-maps a number from one range to another. That is, a value of fromLow would get mapped to toLow, a value of fromHigh to toHigh, values in-between to values in-between, etc.

val = map(val, 0, 1023, 0, 180);

I then proceeded in making the servo rotate by assigning val to analogWrite.

analogWrite(servoPin, -val);

I added a delay of 15milliseconds just to give the board and components time to process.

delay(15);

I compiled this code with COMMAND + R to see if there was any error in the code. Since everything was fine,

I proceeded to upload the program to the board. To do so, I did the following steps:

  1. Select the port

port

  1. Select the clock (the attiny44 has 8MHz)

clock

  1. Choose the processor (ATtiny44)

processor

  1. Choose the programmer (USBtinyISP)

programmer

Once I did this, I uploaded the program using a programmer. This is important because if you upload directly it won’t work. To upload using a programmer you can both do Sketch > Upload using a Programmer or do Command + SHIFT + U.

Done this, the servo started to move as you can see in the following video.

πŸ“ Hero video

Here is the hero video that shows that when I rotate the potentiometer, the servo rotates accordingly.

gif

πŸ‘‘ Group assignment

Group assignment page


Last update: November 12, 2022