Welcome to the N1IR Electronics Website. Totally off the cuff, one take, unrehearsed video projects for anyone interested in amateur radio, electronic design, makers, hardware hackers and science.

Get off your duff and build something!
Training the hand and mind since 1982.

Wednesday, March 26, 2014

Line Following Robot, Part 2

Stay tuned as more stuff will be updated!

As promised from Part 1, http://www.n1ir.com/2014/01/been-over-month.html

Here is the tech info on the robots. So far we've produced 45 units with no problems.  All grades 9, 10, 11 and 12 assembled both boards with no issues.

Originally we thought there might have been soldering issues because traces are tight, but quickly found out if done in sections and tested one section at a time it narrowed down were shorts were.

Another helpful strategy was going over IPC soldering techniques and videos on a practice projects, we found that going over a half dozen project board that were similar in construction increased success of both robot boards.

There are also several other test jigs and programs I made that support this project that will be posted on here as well.

Here is the main board pics
All parts except H-bridge and ATMEGA328 are from donated parts. Thanks to Sager Electronics and Massa Products for there donation.
 Main Board Traces

Partial assembled Opto Board Version 666 Really Version 6 but hit the key to many times hi, hi

 Main board / Optoboard schematics Version 5

This is version 5, I still have to put in values for components. Sorry this was drawn on the fly as corrections were made hours before post production. Version 6 coming soon!

Noticed we dumped the Mega16U2 USB bridge chip that is on the UNO and swapped it for the FTDI cable for simplicity.

Robot with older Optoboard

This is the preproduction version, as of this writing the post production are being assembled next week, more pics coming soon. If you notice on new optoboard the spacing between the QRD1114 is smaller and there are an addition of two LED side markers. We also swapped batteries instead of 3 AA Alkaline, in post production we are using 4 AA NIMH.

Chassis Mech Drawings

Board Mech Drawings



We are running the ATMEGA 328 with the Arduino UNO boot-loader, all programming can be accomplished by using Arduino IDE under "Arduino UNO Board" originally we were going to use the internal oscillator to reduce cost, but ruled this out for internal timing issues, we wanted a simple platform for a student to use without modifying the Arduino IDE environment.
Here is the main program with comments, the first part is the tone library since none of the students laptops have it preloaded in the arduino software set. The program plays a melody then follows a black line, two led on the sensor board indicate direction of turn.

So far we are only using 3 out of 5 optical sensors, the outermost ones will control the response time to center line, ie outer will return to center faster than inner. We are also looking into using the PID control library, but for now it's a simple proportional on/off control loop.

// All lines below define the frequesncy of each tone
// Do not change any of those lines in this section
  #define NOTE_REST 0
  #define NOTE_B0  31
  #define NOTE_C1  33
  #define NOTE_CS1 35
  #define NOTE_D1  37
  #define NOTE_DS1 39
  #define NOTE_E1  41
  #define NOTE_F1  44
  #define NOTE_FS1 46
  #define NOTE_G1  49
  #define NOTE_GS1 52
  #define NOTE_A1  55
  #define NOTE_AS1 58
  #define NOTE_B1  62
  #define NOTE_C2  65
  #define NOTE_CS2 69
  #define NOTE_D2  73
  #define NOTE_DS2 78
  #define NOTE_E2  82
  #define NOTE_F2  87
  #define NOTE_FS2 93
  #define NOTE_G2  98
  #define NOTE_GS2 104
  #define NOTE_A2  110
  #define NOTE_AS2 117
  #define NOTE_B2  123
  #define NOTE_C3  131
  #define NOTE_CS3 139
  #define NOTE_D3  147
  #define NOTE_DS3 156
  #define NOTE_E3  165
  #define NOTE_F3  175
  #define NOTE_FS3 185
  #define NOTE_G3  196
  #define NOTE_GS3 208
  #define NOTE_A3  220
  #define NOTE_AS3 233
  #define NOTE_B3  247
  #define NOTE_C4  262
  #define NOTE_CS4 277
  #define NOTE_D4  294
  #define NOTE_DS4 311
  #define NOTE_E4  330
  #define NOTE_F4  349
  #define NOTE_FS4 370
  #define NOTE_G4  392
  #define NOTE_GS4 415
  #define NOTE_A4  440
  #define NOTE_AS4 466
  #define NOTE_B4  494
  #define NOTE_C5  523
  #define NOTE_CS5 554
  #define NOTE_D5  587
  #define NOTE_DS5 622
  #define NOTE_E5  659
  #define NOTE_F5  698
  #define NOTE_FS5 740
  #define NOTE_G5  784
  #define NOTE_GS5 831
  #define NOTE_A5  880
  #define NOTE_AS5 932
  #define NOTE_B5  988
  #define NOTE_C6  1047
  #define NOTE_CS6 1109
  #define NOTE_D6  1175
  #define NOTE_DS6 1245
  #define NOTE_E6  1319
  #define NOTE_F6  1397
  #define NOTE_FS6 1480
  #define NOTE_G6  1568
  #define NOTE_GS6 1661
  #define NOTE_A6  1760
  #define NOTE_AS6 1865
  #define NOTE_B6  1976
  #define NOTE_C7  2093
  #define NOTE_CS7 2217
  #define NOTE_D7  2349
  #define NOTE_DS7 2489
  #define NOTE_E7  2637
  #define NOTE_F7  2794
  #define NOTE_FS7 2960
  #define NOTE_G7  3136
  #define NOTE_GS7 3322
  #define NOTE_A7  3520
  #define NOTE_AS7 3729
  #define NOTE_B7  3951
  #define NOTE_C8  4186
  #define NOTE_CS8 4435
  #define NOTE_D8  4699
  #define NOTE_DS8 4978
// This is the end of the tone definitions section

// This part of the file defines the notes of the start song
// and the duration of each note
// You need to insure that the # of notes on melody line
// must equal the # of note durations listed
// Initially there are 8 notes, including a rest, and 8 note
// durations. Program fails if the above condition is not met
    int melody[] = {NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, NOTE_REST, NOTE_B3, NOTE_C4};
    int noteDurations[] = {4,8,8,4,4,4,4,4};
// This is the end of the section that plays the start song

// This is the section that defines integer variables and assigns
// pin numbers or sets initial values of those variable
    int CenterIR = A3;
    int DriverIR = A4;
    int PassengerIR = A2;
    int EXDriverIR = A5;
    int EXPassengerIR = A1;
    int DriverPWM = 3;
    int DriverD = 9;
    int DriverC = 10;
    int PassengerPWM = 6;
    int PassengerD = 5;
    int PassengerC = 2;
    int CenterIRValue = 0;
    int DriverIRValue = 0;
    int PassengerIRValue = 0;
    int EXDriverIRValue = 0;
    int EXPassengerIRValue = 0;
// This is the end of the section that defines integer variables
// This is the section called void setup that executes only once
  void setup()
    pinMode (12, OUTPUT);
    pinMode (13, OUTPUT);
    pinMode (DriverPWM, OUTPUT);
    pinMode (DriverD, OUTPUT);
    pinMode (DriverC, OUTPUT);
    pinMode (PassengerPWM, OUTPUT);
    pinMode (PassengerD, OUTPUT);
    pinMode (PassengerC,OUTPUT);
    digitalWrite(DriverD, LOW);  //Direction of Motor LOW is FORWARD ALWAYS
    digitalWrite(DriverC, HIGH); // Brake set to OFF ALWAYS
    digitalWrite(PassengerD, LOW);  //Direction of Motor LOW is FORWARD ALWAYS
    digitalWrite(PassengerC, HIGH); // Brake set to OFF ALWAYS

// this is the loop that plays the notes, again you need to
// have the correct number of notes listed. Initially 8.
      for (int thisNote = 0; thisNote < 8; thisNote++)
        int noteDuration = 1000/noteDurations[thisNote];
        tone(11, melody[thisNote],noteDuration);
        int pauseBetweenNotes = noteDuration * 1.30;
// this is the end of the loop that plays the the tones, initially 8.    
// This is the end of the loop section called void setup that executes only once
//This the start of the loop section called void loops that loops until reset switch pushed
  void loop()
    CenterIRValue = analogRead(CenterIR);
    DriverIRValue = analogRead(DriverIR);
    PassengerIRValue = analogRead(PassengerIR);  
    EXDriverIRValue = analogRead(EXDriverIR); //*****NOT WIRED YET*******
    EXPassengerIRValue = analogRead(EXPassengerIR);  //*****NOT WIRED YET*******
  if (CenterIRValue >= 600)
      analogWrite(DriverPWM, 175); //255 = Full Speed
      analogWrite(PassengerPWM, 200); //255 = Full Speed
      digitalWrite(12, LOW);
      digitalWrite(13, LOW);
  if (DriverIRValue >= 600)
      analogWrite(DriverPWM, 50); //175 = Medium Speed
      analogWrite(PassengerPWM, 175); //255 = Full Speed
      digitalWrite(12, HIGH);

  if (PassengerIRValue >= 600)
      analogWrite(DriverPWM, 150); //255 = Full Speed
      analogWrite(PassengerPWM, 50); //175 = Medium Speed
      digitalWrite(13, HIGH);
// This section is not initially used but allows you to do something
// when the outermost sensors encouter the line, maybe turn faster?

 if (EXDriverIRValue >= 45)
     analogWrite(DriverPWM, 50); //50 = Slow Speed
     analogWrite(PassengerPWM, 225); //255 = Full Speed
     digitalWrite(12, HIGH);

 if (EXPassengerIRValue >= 40)
     analogWrite(DriverPWM, 225); //255 = Full Speed
     analogWrite(PassengerPWM, 50); //50 = Slow Speed
     digitalWrite(13, HIGH);
      delay(5); // Reaction Time before you check status of sensors and next loop starts
       // PS: You are in an infinite loop until you reset arduino board
       // code flow returns to the start of "void loop()" first bracket {
// This is the end of the void loop and the program never gets to this point given infinite loop.