Wednesday, June 15, 2016

The Refit is coming along

The last few days have been spent refitting and re-wiring the robot to accomodate the EZBV4 controller and the Arduino's and new power supply.

The robot is now 12V powered from one battery mounted below the main deck between the front wheels.  From there the power is routed to a fuse, and a switch and then to a DC-DC converter which provides 6V to another switch and is then routed to the EZBV4 and the Arduino's for computer power.  The 12V power is routed to the two motor controllers to control the steering motor and the drive motor.


Not the neatest wiring, but I am clearing it up as I go...


The EZBV4 controller wired to the motor controllers.


The original Hero Jr. Speaker mount.


Rewired the back panel for the 12v switch, the 6v switch, a USB port and the battery charging port.


Drive Motor


Drive motor controller.  Steering Motor and control in the background.


I have the original distance sensor, light sensor, IR sensor.


Original keypad and LED matrix.  All are being used in the new build.



Getting ready to put the rest of the skins on...

Sunday, June 12, 2016

Hero Jr. Gets an Overhaul of all Wiring, Controls and gets Speech Recognition

I have been inactive for a while while rethinking the controls in the Hero Jr. Robot.
The large servo I had to turn the wheel was problematic in that it jittered when standing still under power and had a hard time with the load even though it was rated at a much higher capacity than that of the robot's weight.
I also had a few issues with the drive motor controllers.
So, in the end, I replaced them both, again.
Now, I have rewired the robot to meet the requirements of both motor controllers, and have a 12v battery system in place with a DC-DC 6v converter to power the function controllers.
Also, since adding an EZBV4 controller, I now have speech recognition enabled.
I am happy to say the basic motor controls are working, and here is a short video of that functionality.
I will detail all wiring and controls a little later this week.



There are still some commands that are not defined, but the vocabulary will grow.  I will also most likely change the voice level and add a nicer microphone.

I also have created a web app that will allow the control of the robot from my cell phone...more on that later as well.


Sunday, March 20, 2016

Experimenting with the Arduino C Code

Sunday, March 20th, 2016

Today I am experimenting with the Arduino C Code to see what limitations I might have on creating libraries for different routines within the robot.

I wanted to create a few simple routines to report the status of different functions while the robot is active and also when in a self-test mode.

The first thing I created was an SOS mode where I can flash and L.E.D. (Light Emitting Diode) in the Morse Code for S.O.S. (the Distress Signal).  The S.O.S. was first introduced by Germany in 1905 as a distress signal adapted for Maritime Shipping.  Being German in origin, I doubt it actually stands for Save Our Ship, but that was a common English adaptation of the meaning.  It was likely adopted simply because the SOS are fast, easy, Morse Code symbols to generate (dot, dot, dot, dash, dash, dash, dot, dot, dot).

If you want to know more about Morse Code, there is plenty of information on Google.

So, getting an LED. to flash with an Arduino is not a difficult chore.  In fact, they have a blink program in the examples library that will make one flash if you just want a test program.  That is usually the most common program run.

What I wanted was a way to store a library of symbols and call them in code so that I used very little actual program space.

To make an LED blink, all you really need to do is connect one via a small breadboard with a resistor between ground and you are all set. Power the pin connected to your signal on the LED High and it will light up.  Most Arduino's have a built in LED on Pin 13, so I used that for this first test.

Looking at the code, we will set the Signal Pin to 13 with:

int _sp(13);

So, now the variable _sp means 'Use Pin 13' in the program.

Then in the Setup portion of the program, we make sure to set this pin to be an OUTPUT.  That means we will either give it 5 Volts or take the 5 Volts away.

  pinMode(_sp, OUTPUT);

Now that we have a variable describing what pin to give power to, we just need to tell the Arduino board when we want to give it power and in what kind of a pattern.  By setting the pin 13 High and Low we can give the 5 Volts or set it to 0 Volts (take the 5 Volts away).  This also means turning the LED ON (High, or +5 Volts) and turning the LED OFF (Low, or 0 Volts).  We can use a Delay in between these to leave the LED on or off for a certain amount of time.
Using a Delay command with a time in milliseconds (1000 milliseconds is equal to 1 second) will give the dots or dashes needed to have 3 short flashes and 3 long flashes and 3 short flashes again.

The first version of the program I came up with to test this theory was the following.

/*
 SOS Flash
 This is an experiment with pulse for an LED
 The aFlash will be turned into a library call.
 The SOS will be turned into a library call.
*/

// Set the signal pin that has the L.E.D
int _sp(13);

// the setup function runs once when you press reset or power the robot up.
void setup() {
// initialize signal pin as an output.
  pinMode(_sp, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {

//Do an SOS (...---...)
 _SOS();

}


void _SOS() {
/* Three short, Three long, Three short
 *  that is the SOS Signal (...---...)
 */
 int x;
 int y;
 for( x = 0; x < 3; x++) {
  for( y = 0; y < 3; y++) {
   if(x == 1) {
    _aFlash(800);
   }
   else {
    _aFlash(250);
   }
  } //End Y Loop
  delay(1000);
 } //End X Loop
 delay(2000);
}

//Sub for a flash with delay time between high and low as variable.
int _aFlash(int _dTime) {
     digitalWrite(_sp, HIGH);
     delay(_dTime);
     digitalWrite(_sp, LOW);
     delay(_dTime);
     return 0;
}


If you read through this, it is not really too complicated.
After setting _sp to pin 13 and setting pin 13 as an output, we use the Loop to call our _SOS program.

// the loop function runs over and over again forever
void loop() {

//Do an SOS (...---...)
 _SOS();

}

Next we have to define that _SOS function in the program.  I am using it as a function type void since it will not return any values back to the program when it is called.

void _SOS() {
/* Three short, Three long, Three short
 *  that is the SOS Signal (...---...)
 */

The first thing in this function is to set two variables as integers using:

 int x;
 int y;

These are going to be our counters for the function so that we can control how many times to flash the LED and how many times we want to flash it either long or short.

Next we have 2 loops that will set up the flashes.

 for( x = 0; x < 3; x++) {
  for( y = 0; y < 3; y++) {
   if(x == 1) {
    _aFlash(800);
   }
   else {
    _aFlash(250);
   }
  } //End Y Loop
  delay(1000);
 } //End X Loop

The first one with X starts by setting X to 0, then while X is less than 3, increase X by 1

for( x = 0; x < 3; x++) {

This means that on the first run though, X is now 0...

The next statement says to start Y at 0, and while Y is less than 3, increase Y by 1
  for( y = 0; y < 3; y++) {
So, Y is now 0 also.

Then we check to see if X is equal to 1
 if(x == 1) {
And since it is actually 0, that means that we go to the Else line (if X was equal to 1 we would go to the next line...but now we get to skip over that and to the the Else line.

The Else line calls a function called aFlash with a value of 250.  The aFlash program is a little further down and looks like this:

//Sub for a flash with delay time between high and low as variable.
int _aFlash(int _dTime) {
     digitalWrite(_sp, HIGH);
     delay(_dTime);
     digitalWrite(_sp, LOW);
     delay(_dTime);
     return 0;

This sub declares that it will return an Integer if it returns anything at all and has an Argument (which means it requires you to give it a value when it is called) and the argument is a variable called dTime which is really the amount of the delay time we want to hold the LED either ON or OFF for.
Now, since we called _aFlash(250) we used the (250) as the argument to supply the variable dTime with a value of 250 (which is a delay time that I mentioned earlier was in milliseconds...so 250 milliseconds or 1/4 of one second...really fast!).

The function _aFlash then performs a digitalWrite on the _sp pin (pin 13, remember) and sets it to HIGH...this turns ON the LED.
Then it delays for 250 milliseconds, then does a digitalWrite on the _sp pin again and sets it LOW which turns it OFF, and keeps it off for 250 milliseconds.

The function in this case does not need to return anything back to our _SOS function so we set the return to 0 (which is actually an integer as we originally called _aFlash as returning an integer).

We jump back to _SOS now after we have flashed the LED on and off really quick, and we then loop back to Y, which is now getting the Y++ so now it is 1.
Since there is no condition for Y, only X and X is still 0, we just call _aFlash again with the same 250 ms delay time and flash the light fast a second time.  Then do a Y++ to make Y 2, which is still less than 3 so we call _aFlash again and flash the LED fast one more time...that is the first three fast blinks because now we do Y++ again and so Y would be 3  and that would end this loop since the For statement says to only loop while Y is Less than 3.

Now we delay for 1000 milliseconds (which you might remember is 1 second) and then we return to X. Now X gets the X++ and X is now equal to 1.

In the loop, if X is equal to 1 we are going to drop back to Y again and run through the Y loop again 3 time, calling aFlash again, but now with a longer delay time of
800 milliseconds.  This means that the LED will go ON, stay on for almost a full second (instead of 1/4 of a second like the first 3 times) and then go OFF, and stay off for almost a full second.  This will give us the 3 LONG blinks, and then do a X++ again to set X to 2.  Since X is now 2, which is less than 3 we will hit the Y loop again and since X is not equal to 1 anymore the delay time goes back to 250ms or 1/4 of a second for the 3 loops through Y, giving us 3 fast blinks.  Then we update X with X++ and now it is equal to 3, which ends our X loop and so we drop out to the line after the X loop which gives us a delay of 2000 which means that we will do nothing for 2 seconds, and then we will go back to the start of the void loop() function and start the whole process over again doing 3 fast blinks, 3 long blinks then 3 fast blinks again...forever.

This code will actually get shortened a little but externalizing the _aFlash() function and the _SOS() functions into header files that will become part of a library of headers we can use for the robot which means we will actually just call them at the beginning of the program and then we can have less code in the main loop.

More on that tomorrow...enough for tonight.  Here is a short, dark video of the small Arduino board running the program.


In the next day or so, I will show how to externalize some of the functions so that the code is able to be called over and over again without having to list the whole function each time you want to use that piece of code.


Monday, March 14, 2016

Bad Soldering...

Monday, March 14th, 2016

It has been busy here and I have not had much time for the robot the last few days.
Tonight, I had a few minutes and decided that even though I am tired, I would try and solder up a few things on a small circuit board.  It turned out to be a mistake.  After the first hole, the flux heated up and ran down the board and the solder just melted together on some contacts.



This messed up my board beyond repair and I put the soldering iron away.  Bad luck for me.

I think I am going to keep designing the circuit in Fritzing and then make a board of my own so that I can solder to traces instead of on these small boards...but I still might have to make a prototype on one of these to make sure the circuit works.

Tomorrow, I will connect up a few components and try again!


Wednesday, March 9, 2016

Revised Steering...again.

Wednesday, March 9th, 2016

So, after trying all combinations of sensors for the steering limits (Hall Effect, Micro-switches, and hard stops with current shut off), I did not have a good solution yet.
I decided that since the limits were one issue, and holding the wheel straight while running was another issue, I would go back to trying a servo motor.  But, not just any servo motor...a 1/4 scale gigantic torque-ridden beast that might be able to do the job!  I got the idea watching a video of a couple guys that built a 1/4 scale model airplane out of aluminum and flew it!  I thought if the servos could deal with that, they should be able to push the wheel on my 18 pound robot back and forth.
Scouring the web, I found a place that had not only the giant servo, but nice aluminum mounting brackets...out came the credit card.

After getting my package in the mail, I set about removing all the components I had recently and very carefully fit together (for the second time) and when I got back down to the bare chassis, I drilled holes and mounted my new servo.  After mounting it, I had to make a 3/8" dowel with a hole through it for the connection to the steering plate below.  The hole was so that a set screw could be mounted to keep the whole thing from slipping when under pressure while turning.

I got the whole system mounted up and then connected the H-bridge back on again because that was going to power the drive wheel like it was originally supposed to.

Here is how the whole thing looks now.



Once everything was mounted, I placed the EZ_Robot controller inside to see how everything would fit.  I think the EZ-Robot Micro-controller will handle the steering of the robot and the interface to my cell phone and computer.  That seems like the easiest way to work it out at the moment.
I will use an Arduino Mega up top to power all the head sensors, the keypad and LED's.  I will also use Arduinos for the arms to control them and synchronize everything through a few drivers and libraries I am making for the Arduinos.

My goal now is to try and get this robot rolling by the end of the weekend so that I can start working on my circuit boards for the sensors and then get the arms together.

I am starting to feel more ideas in my head and I want to keep working while they are all still making some sense to me.



The two collars above are holding a 3/8" shaft with set screws travelling through it to keep it from slipping while the wheel is turning.

Tuesday, March 8, 2016

Setbacks and Updates!

Tuesday, March 8th, 2016

Well, I had a few setbacks in the last few days.  It seems that the test setup I had with the Arduino and the breadboard mounted on a plate with power lugs was my issue.  I had the Arduino board set up so that it touched the metal base mounting plate and it shorted out the Arduino...but not completely!

I noticed that when connecting sensors on Friday and Saturday, that I was not getting good, consistent readings.  By Saturday afternoon, after much testing I thought for sure the sensors were just junk...so I ordered a few more and decided to wait and see what happened with the new ones.

The new sensors arrived, and while testing I was getting the same readings!  I could connect to the Arduino, upload to it, but its output was all useless!  This made me switch to another Arduino board and hook up the sensor again and I still got garbage output...with the new sensors and new Arduino board!  So, I waited for more sensors to arrive and when they did, I got good readings...for about 30 minutes...then something went wrong.  Back to garbage on output.

I went through some basic testing only to find out that I had some outputs touching the base plate which shorted the Arduino and the sensors and caused all my problems.

To fix this, I drilled holes in the metal base plate and used acrylic standoff mounts to place the Arduino about 1/4" above the plate and secured it with a few screws into the standoffs.

No more shorting and the tests will now continue!

I ordered a few more sensors for sound and for a real time clock setup and will test those later this week when they arrive.

In the mean time, I am digging out the arm components so that I can mount the servo's in them.

More on this later!


Tuesday, March 1, 2016

Speech! The Robot Gets a Voice!

Tuesday, March 1st, 2016

Today was another busy day, but I took a little time at lunch and then a little more after work to hook up the Emic2 speech chip and see if I could program some voice into the robot.
The reason I picked the Emic2 was because I can feed it strings and it will speak whatever I type with very little fuss.
There are a few other speech chips available, and I actually have the original Hero Jr. speech chip, but it has such limited capability compared to the newer technology, that I thought I would give this one a try.

The installation of the chip is pretty simple, there are really only 4 wires.  You have +5V and Ground to power the chip, then Sin and Sout where you pass the serial in and serial out commands from the microprocessor.  Since I am using Arduino boards as my processors, I grabbed an Arduino Mega and plugged in the 4 wires, found an old speaker and connected the 2 wires from that to the Speaker + and - leads.  There is also a headphone jack where you can plug in an external speaker as well.

After a short bit of coding, I had the Emic2 speaking and running his demos in English and in Spanish!  Then he sings a song...















Once I finish learning the speech commands, I will make a speech library of phrases and place them on an SD card and have those phrases available to be read in response to other commands.  I will likely number the responses and then make an array of (n) units and each time I need a phrase, I can command emicSerial.print(n); and it will call the phrase I need.
Other speech can be live as it is parsed from the voice recognition...which I will get to later on.


The code I used is below.
/*
  This program provides a simple demonstration of the Emic 2 Text-to-Speech
  Module. Please refer to the product manual for full details of system 
  functionality and capabilities.  You can program this chip in a variety
  of ways and they have examples for Parallax, and Arduino.

*/

// include the SoftwareSerial library so we can use it to talk to the Emic 2 module
#include <SoftwareSerial.h>

#define rxPin 50     // Serial input (connects to Emic 2 SOUT)
#define txPin 51     // Serial output (connects to Emic 2 SIN)
#define ledPin 13    // Most Arduino boards have an on-board LED on this pin

// set up a new serial port
SoftwareSerial emicSerial =  SoftwareSerial(rxPin, txPin);


void setup()  // Set up code called once on start-up
{
  // define pin modes
  pinMode(ledPin, OUTPUT);
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  
  // set the data rate for the SoftwareSerial port
  emicSerial.begin(9600);

  digitalWrite(ledPin, LOW);  // turn LED off
  
  /*
    When the Emic 2 powers on, it takes about 3 seconds for it to successfully
    intialize. It then sends a ":" character to indicate it's ready to accept
    commands. If the Emic 2 is already initialized, a CR will also cause it
    to send a ":"
  */
  emicSerial.print('\n');             // Send a CR in case the system is already up
  while (emicSerial.read() != ':');   // When the Emic 2 has initialized and is ready, it will send a single ':' character, so wait here until we receive it
  delay(10);                          // Short delay
  emicSerial.flush();                 // Flush the receive buffer
}

void loop()  // Main code, to run repeatedly
{
  // Speak some text
  //emicSerial.print("N1\n");      //Change the Voice Tone here...1-9 are valid voices.
  emicSerial.print("V15\n");
  emicSerial.print('S');
   // Send the desired string to convert to speech
  emicSerial.print("Holy Crap spackel!");
  emicSerial.print("Hello. I would like to demonstrate some of my features."); 
  emicSerial.print("Now that I can talk, I might not shut up!");
  emicSerial.print('\n');
  digitalWrite(ledPin, HIGH);         // Turn on LED while Emic is outputting audio
  while (emicSerial.read() != ':');   // Wait here until the Emic 2 responds with a ":" indicating it's ready to accept the next command
  digitalWrite(ledPin, LOW);
    
  delay(500);    // 1/2 second delay
    
  // Run 3 demos...
  emicSerial.print("D0\n");           // Demo 1 in english.
  digitalWrite(ledPin, HIGH);         // Turn on LED while Emic is outputting audio
  while (emicSerial.read() != ':');   // Wait here until the Emic 2 responds with a ":" indicating it's ready to accept the next command
  digitalWrite(ledPin, LOW);
  emicSerial.print("D2\n");           // Demo 2 in spanish.
  digitalWrite(ledPin, HIGH);
  while (emicSerial.read() != ':');
  digitalWrite(ledPin, LOW);
  emicSerial.print("D1\n");           // Demo 3 is Emic singing 'Daisy'
  digitalWrite(ledPin, HIGH);
  while (emicSerial.read() != ':');
  digitalWrite(ledPin, LOW);


 // Below is a loop to keep the Emic from repeating over and over...basically it just flashes the led on and off...
  while(1)      // Demonstration complete!
  {
    delay(500);
    digitalWrite(ledPin, HIGH);
    delay(500);              
    digitalWrite(ledPin, LOW);
  }
}