Aug 20, 2014

Programming an ATtiny85 with an Arduino

How to Wire the ATtiny85

The ATtiny85 is a cheap, low functioning microcontroller perfect for small applications, like an automatic fish-feeder. They're small, have low power consumption, and are cheap ($1-2). The ATtinys are made by Atmel, just like the microcontroller that powers an Arduino. What does this mean? It means the ATtinys are programmable with the Arduino software by using an Arduino as a programmer.

When I searched for tutorials on how to wire the Arduino Mega to the ATtiny for programming, it took me very long to find something. Most of the tutorials used an Arduino Uno, which I don't have. When I found out how to do it, I used a breadboard to wire the Tiny to the Mega. Here is an illustration of where to connect the wires:


How to Program the Chip

Now that I had the Arduino wired to ATtiny, I just had to program it. The pins that are indicated in the datasheets are not the same as in the program. For example, pin 3 on the ATtiny is not pin 3 in the sketch, it's actually pin 4. This is an equivalency illustration.




To program the ATtiny, you must first upload the "Arduino as ISP" sketch to the Arduino you use as a programmer. You can find in the Arduino IDE under Files>Examples>ArduinoISP. Once that is completed, you have to download the ATtiny library here. Unzip the file and copy the folder "attiny" into the Arduino folder "hardware". Check the "attiny" folder and make sure that it's contents are "boards.txt" and a folder labeled "variants". Open the Arduino IDE, or restart it if it's open, and there should be more options in Tools>Board the start with "attiny". You can upload a sketch to the board right away under the board "ATtiny85 (internal 1 MHz clock)" or you can easily configure the board to run at 8 MHz. This takes one extra step. Under Tools>Board select "ATtiny85 (internal 8 MHz clock)". Then select "Burn bootloader" under Tools. This makes the chip 
run at 8 MHz.

This is my blink sketch. I used the Arduino to power the ATtiny.


May 9, 2014

Explorer Robot

Sorry for not posting anything for so long! I have been busy and I put electronics projects on the back burner for a while. I have often wanted to make a robot though. I finally decided to take the plunge and just order some parts. I'm a fan of DIY and so I decided against buying it as a whole kit. (I am also a huge fan of saving money and kits are expensive!) This robot didn't have to be very robust or of high quality so I bought cheap "Made in China" parts off of eBay and Amazon.com. My robot design was roughly sketched out in my brain, though it would be unwise to do so on a more complex build. This is the robot I built and these are the parts I ordered:




Bill of Materials:
  • New Motor Smart Robot Car Chassis Kit Speed Encoder Battery Box For Arduino
  • H-bridge Stepper Motor Dual DC Motor Driver Controller Board For Arduino HG-7881
  • 5M Flexible 22AWG Stranded UL1007 Hook-Up Wire (Black)
  • 5M Flexible 22AWG Stranded UL1007 Hook-Up Wire (Red)
  • 100 Pack Black Cable ZIP Ties 8 Inch 40LBS Nylon (I should've bought smaller ones)
  • Mini USB Nano V3.0 ATmega328 5V Micro-controller Board Arduino
  • 1 pcs Ultrasonic Module HC-SR04 Distance Measuring Transducer Sensor for Arduino
  • SG90 9-gram Micro Servo
  • 4 AA NiMH Rechargeable Batteries
  • a small on/off switch
  • a little scrap of thin wood or plastic
  • some double-sided tape
Tools:
  • soldering iron
  • solder, rosin-core
  • wire cutters
  • wire strippers
  • de-soldering tool (you'll definitely want this!)
  • screwdrivers
  • a computer for programming the Arduino
  • the Arduino IDE (Download Here)
  • a rotary tool with cutting discs or a small craft saw (the rotary tool is better)
As I didn't have my blog in mind when I made this, I don't have any pictures during the build. That is unfortunate but the parts I ordered had good documentation and it didn't take too much puzzling to put it together. 

The chassis kit comes with two rubber drive wheels, one back caster wheel, a battery holder, two geared motors, motor leads, nuts and bolts, two black tachometer discs, and a clear plastic base to screw everything to. I put the battery holder in the back, where it receives the best support from the wheels; it is the heaviest part by far. The servo and distance sensor are mounted on the front to scan where it moves. The Arduino is also mounted in the front with the USB hub pointing outwards. The on/off switch is close to the Arduino. 

I cut holes in the plastic base for the Arduino pins to go through. I simply mounted it with some double-sided tape. The servo and switch also are mounted in holes cut with the rotary tool. Be careful as the grip on the rotary tool will grind the plastic away!



This isn't too bad for the frame but it looks ugly. The back wheel is easily screwed into the base with four nuts and bolts. The distance sensor is mounted on the servo with a small piece of wood about 1/8" thick and two zip ties. The wires are soldered directly to the pins, as with all the wires on this robot. They are held together by some small zip ties I found in my garage. I routed them through a large hole that was already in the center of the board. From there they connect to the Arduino's pins underneath the plastic base. The H-Bridge is screwed onto base with some extra hardware that came with the chassis kit. The drive wheels are mounted just by pushing them onto the plastic axles. Same goes with the black tachometer discs. You don't really need the tachometer discs, but I put them on anyways as I hope to implement them in the future. The plastic motor mounts are screwed into some metal bracket like objects that are in turn screwed onto the frame.

You should be able to find the documentation for the electronic components online. The switch is wired like this, pin 1: nothing, pin 2: positive wire from battery, pin 3: all the positive output wires. The HG-7881 H-Bridge is the Chinese version of the L9110 driver. (Driver Code Here!) It has 6 pins, BI-A, BI-B, GND, VCC, AI-A, and AI-B. GND is hooked up to the ground wire and VCC is hooked up to the positive terminal on the on/off switch. The rest of the pins have to be wired to PWM pins on the Arduino.

On the Arduino, the ground wire to the battery is directly soldered to the GND pin of the Arduino. The positive wire is wired to the 5v pin. Since the batteries are wired to the 5v pin, you can only use 1.2v rechargeable batteries or you might fry your Arduino. The 5v pin is an unregulated input pin. HC-SR04 example sketch can be found here. Its GND and VCC pins are hooked up like the H-Bridge. Its trig and echo pins are soldered to two digital pins as shown in the example sketch. The positive and ground wires on the servo are wired just like the distance sensor. Its signal lead is wired to the D11 pin on the Arduino. Once you have it all wired up, get ready to transition to a computer nerd! Just don't put away all your soldering tools yet as you may still need them.

This all seemed pretty difficult until I had to sit down at the computer and write the software to bring it to life. This is the code:


// Robot Code version 2
// May 5, 2014
// James Taverne
// This code is not completely original. Some credit goes to bajdi.com for the motor driver code.

#include <Servo.h>

Servo myservo; // create servo object to control a servo

const int AIA = 9;  // (pwm) pin 9 connected to pin A-IA 
const int AIB = 5;  // (pwm) pin 5 connected to pin A-IB 
const int BIA = 10; // (pwm) pin 10 connected to pin B-IA  
const int BIB = 6;  // (pwm) pin 6 connected to pin B-IB 
 
byte speed = 255;  // change this (0-255) to control the speed of the motors 

int minDuration = 888; // distance it which to stop in order to prevent the robot getting stuck against a wall
                       // 888 / 74 / 2 = 6 in 

long duration;

void setup()
{
  myservo.attach(11);
  pinMode(AIA, OUTPUT); // set pins to output
  pinMode(AIB, OUTPUT);
  pinMode(BIA, OUTPUT);
  pinMode(BIB, OUTPUT);
  pinMode(7, OUTPUT);   // attach pin 7 to Trig
  pinMode (8, INPUT);   // attach pin 8 to Echo
  myservo.write(90);
  delay(1000);
}

void loop()
{
  int durations[] = {0, 0, 0, 0, 0, 0};
  int sensorAngles[] = {0, 45, 90, 135, 180, 90};

  Forward();
  
  measureDistance();
  
  if(duration<minDuration)
  {
    Stop();
    for(int i=0; i<6; i++){
      myservo.write(sensorAngles[i]);         // use the servoAngles array to move the servo in 45 degree increments
      delay(400);                             // wait for the servo to reach its position
      measureDistance();
      duration = durations[i];                 // set values in the distances array
    }
    int greatestValIndex = 0;                 // used to find the position of the greatest duration value in the durations array
    for (int i=1; i<5; i++){
     if (durations[i] >= durations[greatestValIndex]){
       greatestValIndex = i;
     }
    }  
      int bestAngle;
      durations[greatestValIndex] = bestAngle;          // if distances measured are not all greater than minDuration, avoid away from the obstacle
      if (bestAngle == 0){                              
       Left();
       delay(300);
      }
      if (bestAngle == 45){
       Left();
       delay(150);
      }
      if (bestAngle == 135){
       Right();
       delay(150);
      }
      if (bestAngle == 180){
       Right();
       delay(300);
      }
    }
  
delay(50); 
  
}

void measureDistance()
{
  digitalWrite(7, LOW);
  delayMicroseconds(2);
  digitalWrite(7, HIGH);
  delayMicroseconds(5);
  digitalWrite(7, LOW);
  duration = pulseIn(8, HIGH);
}

void Forward()
{
  analogWrite(AIA, 0);
  analogWrite(AIB, speed);
  analogWrite(BIA, 0);
  analogWrite(BIB, speed);
}
 
void Backward()
{
  analogWrite(AIA, speed);
  analogWrite(AIB, 0);
  analogWrite(BIA, speed);
  analogWrite(BIB, 0);
}
 
void Left()
{
  analogWrite(AIA, speed);
  analogWrite(AIB, 0);
  analogWrite(BIA, 0);
  analogWrite(BIB, speed);
}
 
void Right()
{
  analogWrite(AIA, 0);
  analogWrite(AIB, speed);
  analogWrite(BIA, speed);
  analogWrite(BIB, 0);
}

void Stop()
{
  analogWrite(AIA, 0);
  analogWrite(AIB, 0);
  analogWrite(BIA, 0);
  analogWrite(BIB, 0);
}

You can download the ino file here. I wish I had a nice wiring schematic to show but I don't have one at this moment. I may, however, make one and post it. Now for the cost analysis:

Robot Car Chassis                                      $12.65
H-Bridge Motor Driver                               $1.72
Hookup Wire (Red + Black)                       $3.36
100 Pack Zip Ties                                       $4.66
Arduino Nano                                             $6.96
Distance Measuring Sensor                          $1.96
9-gram Micro Servo                                    $3.49
4 AA Rechargeable                                     $4.50
Small On/Off Switch                                    $0.50
Double Sided Tape                                      $3.99
-------------------------------------------------------
Total                                                           $43.79

So you could expect to pay between 40 and 45 dollars for this project, as long as you all ready have the necessary tools. This may seem like a lot of money, and it is. But in comparison to a lot of kits out there, it's pretty affordable. Here are some more pictures of the robot as well as a short video of it in action.

Note the metal mounting bracket

I use 4 AmazonBasics AA rechargeable batteries

A cheap TowerPro servo mounted through the frame

My distance sensor mounted using zip ties

The Arduino with the pins through the bottom of the frame





I have plans for a way to make this useless robot useful. When the parts I ordered finally come and I program it all, I'll post an update. Hopefully the next stage goes as well as this part went. If you have any questions, please comment below! I really like reading the comments. Please, do try this at home and tell me how it went!