cr_002 - the excavator.
Introduction.
cr_002 is a whim. What? Is a whim? Yes. My son had a broken toy, an excavator toy, which when working, was managed by a wired controller. But before starting this challenge the wired controller was lost. So the toy was as you see in the picture below.
The challenge was: transform it bringing it to the year 2016. That is, repair the toy’s mechanic, install on it a CPU-board able to manage all peripherals, install a custom electronic board acting as middle-layer between CPU-board and motors, manage the toy remotely by installing a wi-fi unit to control it over air; install a unique power unit (battery) able to send energy to all electronic devices on the excavator. Frankly speaking the toy plastic material was very good and the several modifies haven’t damaged it.
When I decided to start this relaxing hobbyistic activity, I thought: “Simple thing, I read on Internet several people did a similar thing, simple…"
There is an italian proverb saying “from saying to doing there’s the sea in the middle”. I think there will be a similar sentence in every place of the world.
So I’m going to describe what I made and what made me slow (obstacles) during this extremely simpe hobbyistic realization.
Step 1-Mechanic.
The toy has been doned from other child to my son, so the excavator has already past a hard period of its life in other hands. The mechanic was good but damaged. Even if we are talking about a toy, I have to admit is one of the best toys I’ve ever seen. The possible movement were (are) forward, backward, left, right, up and down for the bucket. The bucket was perfect as mechanic and as electric motor. It has been very simply to repair the left-right mechanic, the motor was ok. The main transmission was damaged for several reasons. Even if it was a toy the transmission between wheels and motor was realized by means of differential transmission. Frankly speaking I wasn’t aware how the motor transmits the movement to the wheels in our cars until I opend this toy, and I also learnt go-karts do not have this type of transimission and for that, they have several difficulties to face the curves. The differential transmission makes a different rotation speed for the right and left wheel. It acts in a way that the internal wheel turns slower than the external wheel and so, the car can face better the curve. Maybe, for several toy incident, the gears related to the differential transmission lost their tolerance, so I repaired it with a new metal gear. The left wheel lost the tolerance with its axis so I used resyne glue to repair it. Below the differential gears and the plastic chunck detached from the left wheel.
But, what I was struggling with, it was the gears between motor and wheel axis. From the right picture you can see a strange white box. It contains all gears to transmit rotation from the dc electric motor to the differential transmission of the main axis. Among the gears there was a shaft mounting two plastic gears, one getting the movement from the motor and the other transmitting the rotation to another gear. And the thinnest of the two lost its tolerance with the axis, so when the motor was rotating at high RPM it wasn’t still able to transmit the movement to the axis. But, the hard problem has been the fact, after repaired it, it kept on working for just some second after the completion of the whole excavator. Actually it broke 3 times. Why ?
First the tolerance between axis and gear was alreay lost for the previous use of the toy.
Second, my personal requirement has been making use of one battery as central energy unit; but I chose a cheap battery, payd about 14 euros, extremely heavy; the battery weight was about 2 Kg, so it was a tremendous increase of offort for the little gear.
Third, I increased the emf at the motor pins, adding some Volts to the nominal voltage, so all gears were more stressed. After several tests the axis of the two gears broke in two chunk. Having listened to an advice of a friend of mine, I substituted the gear axis with a chunk of solder electrod (about 2 mm thick). From an electronic point of view I made use of a PWM to power the motor. Indeed the pulse width modulation is great way to change the rotation speed of a motor without loosing torque. In general if you want to put down the speed of a motor you can use a resistor, but doing it, you’re changing the elecromotive force applied to the motor but you’re also changing some of the main parameters of the motor: current, torque. But if in one second (1 sec. is an example) you give power to your motor for 40% of the time and you do nothing in the remaining 60 %, you’re making use of the pulse width modulation, a genial way to reduce motor speed without losing the torque. So replacing the gear shaft and buying an already-done PWM board, I figured out. Actually the pwm has been monuted between the power source and all motors, because the source power is 12 Volt and the motors have all a lower nominal voltage.
Step 2-The heart: BBB.
According to the requirements, I need of a CPU board able to manage the motors and to receive commands through a wifi connection. I thought the easy way to do that was making use of a cpu programmable board, and because I already knew the Beagle Bone Black I opted for that device. The BBB is a single computer boards with a SITARA CPU (1 Ghz) running some Linux distros and providing a few general purpose pins. The board computer does what you want it do (in theory). And how did the BBB come in handy? The board had to manage information coming from a remote client, using a wifi connection whose access point be the BBB board. The BBB had also elaborate the information and set some pins. So in other words, the board was switched on, it had several processes running on it and one of them was in charge of managing a wifi antenna and receiving information from a client connected to the board; the information was processed, and according to the read message(s) some pins were set. If you’re thinking it is(was) as simple as you read these rows you’re wrong.
The BBB doesn’t provide a chip for wifi connection so you have to buy your wifi usb dongle and make it running on the BBB. I chose a not expensive wifi dongle usb: the TP LINK TL-WN725N (with Realtek chipset). If you surf the Internet, you can find several articles about the creation of a Wi Fi Access Point using the Beagle Bone Black. But going deeper and trying to transform what you read into a working device is another story. I wasted much time trying to realise an access point following the instructions found on the web; to realise an AP reliable and working you have to find out the right combination of hardware, software and correct configuration. I lost a couple of weekend to make an AP with a BBB Rev.C the TL-WN725N and the right Linux distro, and the topic is so long I decided to describe the step by step tutorial in another article on this site: Make an access point with the BBB from scratch. Read the article carefully to implement your own AP.
So let’s move on the other requirement aspect. The BBB is now ready to accept wifi connection from a client, assign it an IP address (by DHCP) and receive everything over the air. Now we need of some agent continuosly waiting for a message, process in a predetermined manner the information (we can extract from the message) and change the value of some pin. There are several ways to do that on a linux machine, one of that is writing a C program. In the following lines I’m going to describe the cr_002 server side C program. The whole program, and its client side written in Objective C for iOS deveices, can be downloaded from the download section of this article.
Step 3 -The cr_002 C program.
We are in the 2016 and do you write a C program? Yes it is about 50 years old, but for linux and electronic devices it’s the number ONE. Like each C program cr_002 begins with a main. The main has an infinite loop (see videogames programming) and within it, we make use of the UNIX fork. The fork generates a child process and at the end of it (either it terminates in a right way or in a bad way), the while + the wait() instructions creates it again. The child process call the bbb_open(), the process_command() and the bbb_close();
while (true)
{ if( pid_command == -1 )
{ pid_command = fork();
if(pid_command > 0)
{ bbb_open();
printf(APPLICATION_NAME", launching process_command\n" );
process_command();
bbb_close();
} } pid = wait(&status);
if( pid == pid_command )
{ printf(APPLICATION_NAME", process_command aborted\n");
pid_command = -1; } }
Let’s examine the bbb_open() and the bbb_close() functions; before that you need a little explanation about the BBB pins setting. If you see within the
global.h file you’ll see the following lines
//---------------------------------------------------------------// from operating system//// move down = echo 1 > gpio44/value;echo 1 > gpio45/value;// move up = echo 0 > gpio44/value;echo 1 > gpio45/value;// move right = echo 1 > gpio47/value;echo 1 > gpio26/value;// move left = echo 0 > gpio47/value;echo 1 > gpio26/value;// move forward = echo 1 > gpio27/value;echo 1 > gpio46/value;// move back = echo 0 > gpio27/value;echo 1 > gpio46/value;////// register pin_0 -> gpio45 -> bbb_P8_11 pin -> GPIO1_13 -> 32+13 = 45 OFF-ON of UP-DOWN// register pin_1 -> gpio44 -> bbb_P8_12 pin -> GPIO1_12 -> 32+12 = 44 UP-DOWN// register pin_2 -> gpio26 -> bbb_P8_14 pin -> GPIO0_26 -> 0 +26 = 26 OFF-ON of RIGHT-LEFT// register pin_3 -> gpio47 -> bbb_P8_15 pin -> GPIO1_15 -> 32+15 = 47 RIGHT-LEFT// register pin_4 -> gpio46 -> bbb_P8_16 pin -> GPIO1_14 -> 32+14 = 46 OFF-ON of FORWARD-BACKWARD// register pin_5 -> gpio27 -> bbb_P8_17 pin -> GPIO0_27 -> 0 +27 = 27 FORWARD-BACKWARD////// motor wire colors//// bbb_P8_12 - gray// bbb_P8_11 - white//// bbb_P8_14 - yellow// bbb_P8_15 - brown//// bbb_P8_16 - black// bbb_P8_17 - black////---------------------------------------------------------------
#define COMMAND_LENGTH 2
typedef struct _commands_struct
{ unsigned char command[COMMAND_LENGTH];
} commands_struct;
//bbb_P8_11, GPIO1_13#define BBB_P8_11_BUCKET_ON_OFF 45
//bbb_P8_12, GPIO1_12#define BBB_P8_12_BUCKET_UP_DOWN 44
//bbb_P8_14, GPIO0_26#define BBB_P8_14_TURN_ON_OFF 26
//bbb_P8_15, GPIO1_15#define BBB_P8_15_TURN_LEFT_RIGHT 47
//bbb_P8_16, GPIO1_14#define BBB_P8_16_MOVE_ON_OFF 46
//bbb_P8_17, GPIO0_27#define BBB_P8_17_MOVE_FORWARD_BACKWARD 27
When I decided to manage the three motors of the toy, I opted for a custom electronic board (we are going to see it in the next section) that needed of six pins of the BBB board. Why? Because for each of the three motors, one pin is to manage ON/OFF status the other is for the rotation direction. So I fixed the pins to use, reading the port P8 and P9 features (I advice you the site and/or the book of Derek Molloy http://derekmolloy.ie) and after that, I wrote them in the global.h file. As you see they are the pins 11, 12, 14, 15, 16 and 17 of the P8 port. To use a pin, with the BBB, remember that the symbol P9_XX or P8_YY is just a human notation; for example P9_15 corresponds GPIO1_16; the physical value to address the pin is
[if gte mso 9]>
0
0
1
68
388
extech
3
1
455
14.0
Normal
0
false
false
false
EN-US
JA
X-NONE
differential transmission
the TP LINK TL-WN725N
the excavator, in its initial status
gear to transmit movement to the left wheel, detached and leaning on the right wheel
the BBB pins testing
main shaft gear
next
back to home
white can containing motor gears to transmit
movement to the wheel axis
LINUX
BeagleBoneBlack
Wi Fi
Access Point
pwm board
written by Ivan Cerrato
mapping of the UP key on the storyboard
Step 4 -The cr_002_client iOS App.
Objective C is the main language to write app for Apple devices, so I chose this one and not Swift despite it’s the newest language from Apple. The app is very simple, we have only six button, one for each motor direction. There’s no chance to press two button together, meaning that over the air you can send one message at time. As already said, there are 6 buttons each of them able to send a sequence of “0” and “1” to remotely manage the BBB pins. The sequence of the bit must be the same at server side and client side, otherwise there will be no correspondance between motor to manage at client side and motor pin at server side. If at client side the first pin is the ON/OFF for the bucket motor, the first pin on the BBB has to be electrically wired to the relay responsible to switch on/off the bucket motor. The GUI is tested for the iPad, but it’s so simple that the porting to another iOS device is pretty immediate; for time saving I didn’t create an adaptive GUI, I just tested it on my iPad Air. Now let’s move in more technic details. Having only 6 buttons, you could think there will be only six IBAction, but actually they are seven. The view controller relates to the buttons has 7 IBAction, six for each button and one for the button_stop (common to all button). Why? If you payd attention to the code of the server side you noticed that what comes in input is transferred on the BBB pins; therefore the question is, how is it possible to manage the life cycle of a PIN value and consequentely the life cycle of a motor command? In other word if the pin 1 goes ON, when does it go OFF ? The response is in seventh IBAction.
Tipically the IBAction is fired on the “Touch up inside” event of the button, so when a user releases the button the action is fired, but not now. I wanted that the time the user press the button is the time the related motor stay ON. So when a button is pressed the related action will be fired, I’m firing the action on the “Touch Down” event, when the button is released the comon action button_stop will be fired, I’m firing the action on the “Touch Up inside” event. This way if I press the button “UP” for 1 second, the bucket is going up for just one second (the delay related to the transmission over the air is negligible).
Again, consider the button UP. When the user press the button the action button_bucket_up will be called. this means that a message is going to be assembled and transmitted on a socket to the server. When the button is released the common action button_stop will be called and a new message will be made (the message resets all pins) and transmitted on a socket to the server.
Following the two methods button_stop and button_bucket_up:
- (IBAction) button_stop { [_appDelegate sendCommand: (const unsigned char)STOP_ALL];
}
- (IBAction) button_bucket_up { [_appDelegate sendCommand: (const unsigned char)BUCKET_UP];
}
The message you see in the methods are defined in the Global.h file
#define STOP_ALL 0
#define BUCKET_UP 1
#define BUCKET_DOWN 3
#define MOVE_LEFT 4
#define MOVE_RIGHT 12
#define MOVE_FORWARD 16
#define MOVE_BACKWARD 48
As you see the message STOP_ALL send the value 0 to the server, inducing the reset of all pins. The message BUCKET_UP wil send the message 1 meaning that I’ll send 00000001, that is, switch the motor ON in its default rotation. We send over the air just 1 byte, but the protocol overhead.
Now move on the network section, that is how the client connects to the server. The IBAction methods all call the sendCommand method of the AppDelegate class. What the sendCommand does ? Nothing of special, it does what you could imangine it do. It starts a network connection, makes by means of NSData the message to send, writes on the output stream and closes the connection.
- (void) sendCommand:(const unsigned char )command
{ if(![_ip_address isEqualToString: NO_CONNECTIONS])
{ [self initNetworkCommunicationCommands];
const unsigned char bytes[] = {command,0};
NSData *data = [NSData dataWithBytes:bytes length:sizeof(bytes)];
NSLog(@"%@", data);
[outputStream_commands write:[data bytes] maxLength:[data length]];
[self closeNetworkCommunicationCommands];
}}
The initNetworkCommunicationCommands creates a socket toward the server side using the API CFStreamCreatePairWithSocketToHost that wants the IP address, the server port the read stream and the write stream; after it is set as delegate the same AppDelegate and the currentLoop is used as thread for the API.
- (void) initNetworkCommunicationCommands { CFStreamCreatePairWithSocketToHost(NULL,
(__bridge CFStringRef)_ip_address,
SOCKET_PORT_COMMAND,
&readStream_command, &writeStream_command);
outputStream_commands = (__bridge NSOutputStream *)writeStream_command;
[outputStream_commands setDelegate: self];
[outputStream_commands scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream_commands open];
}
The closeNetworkCommunicationCommands simply closes the connection.
- (void) closeNetworkCommunicationCommands {
[outputStream_commands close];
outputStream_commands = nil;
}
Architecture.
Theres’s a point of weakness in this story, or using a professional word, architecture: if for some reason the iOS app isn’t able to connect to server after having sent the first message, the useful message, the pins on the server side will stay active in its latest state. So if I sent the message "pull up the bucket" but, when I release the button, the message bringing the information of reset pins won’t arrive to the server, the excavator will keep on doing the movement to pull up the bucket. This is, actually, a cons for the above architecture. A pro is it’s extreme simple.
As alternative we could have sent a compound message, with two section; the first bringing the useful information related to the command, the second with the duration of command, maybe in ms. This type of architecture implies the creation of a section, server side, with delay management and threads creation or process forking. I thought we are repairing a toy so the easiness has to be the main directive.
Step 5 -The electronic.
At this point the whole software is ready, we need the electronic to manage the motors. What we have now is the chance to remotely switch to either 0 or 1, six pins of the BBB port P8. What do we need now? First I need of a electronic board able to translate the digital output of the BBB to something can manage the motors. Second, one of the requirement stated that only one power source has to be present on the excavator, so I need some little module able to decouple the main source (battery) from the single power sources that rely to each device. And third, from the applied experience, I need of a PWM to regulate the speed of the motor.
Custom electronic board.
Frankly speaking I not a hardware engineer, I designed the board considering my electronic knowledge and the old hardware available in my drawers. On the BBB the expansion interface is comprised of two 46 pin connectors. All signals on the expansion headers are 3.3V. I wanted to be careful so to decouple the board from the rest of the electronic I made use of opto-decoupler: 4N26, each for every pin; the final state of the custom boards are made from six relays (three of them with 6V dc coil (1 pole), three of them with 12V dc coil (2 poles) …remember old hardware); to manage the relays I used the proven ULN2003; the ULx200xA devices are high-voltage, high-current Darlington transistor arrays. So the outs of the optocouplers drive the uln2003 and the outs of this IC drive the relays. There are three couple of relays, each of them is made from a 6V dc coil and a 12V dc coil; to every 6V dc coil is wired a 100 Ohm resistor beacuse the nominal Voltage to drive the relays is about 12 Volts. The 6V dc coil relays (white in the pictures) manage the switch on/off of the motors, the 12V dc coil relays (blue in the pictures) manege the rotation inversion.
The scheme of the custom board is synthesized to just two of the six relays, but the remaining hardware implementation is obtained copying the alreay provided scheme and using the other pin of the ULN2003A.
Module to decouple power.
You could think: "It’s only a power, what’s the matter?". Calm down. The BBB needs of 5V@2A for a correct working, and you cannot give it a less current because we are using a wifi usb dongle, so we cannot provide a source power of 5 Volt and a current less than 2A. The custom board for the presence of the 12V relays has to work at about 12V (it’s not so mandatory but the voltage has to be around that value); the motors present an apparently little problem. At the origin the power of the motor was about 7,5 Volts, so I thought, I’ll put a resistor between 12V main power battery and every motor solving the problem, but for the bucket and the left-right motor, this solution could be ok, but it’s not ok for the main wheels because I added more than 2 Kg on the excavator (it is only a toy); so you could think eliminating the resistor from the main wheels motor giving it a major Voltage, it could be a solution, but ….actually I broke the main transmission 2 times. At the end, I spent 7 euros to by a little PWM. I placed the little PWM board between the source battery and the three motors; this way they work at a voltage greater than their nominal voltage, but trimming down the period of the PWM you can obtain a slow rotation without loosing couple (you have 12 voltage on each motor, and the current doesn’t go down).
Conclusion.
At this point of the story, we are almost at the end, I think it’s useful to recap all steps. This whim, I cannot find other words, that is transforming a damaged toy into something technologically responding to the year 2016, has been divided into five technical milestones: the mechanic, the BBB setting (another article on this site), the cr_002 server program, the iOS client app, the electronic.The whole toy mechanic has been reviewed and/or repaired. The BBB has been used to manage all toy features: 3 electrical motors. It was in charge of acting as access point and as mini computer (to run the program able to manage the pins of the board). The interface between the BBB and the motors has been realized by means of a custom board. The board was based on six 4N26(optocpuplers), ULN2003A(Darlington transistor arrays), six realys. A common power battery has been used, and two step down voltage modules have been used to give energy to the BBB (5V@2A) and the custom board (about 11,9 Volts). The client has been realized writing an iOS app whose target was an iPad device.
The whim is terminated. The next page is the download section where you can get the cr_002.zip. The archive contanis both the client app, written in Objective C, and the server side C program written for the linux BBB.
devices general schema of the excavator
the custom motor board scheme
back
iOS app snapshot
custom board
work in progress
all switched on
[if gte mso 9]>
0
0
1
40
232
extech
1
1
271
14.0
Normal
0
false
false
false
EN-US
JA
X-NONE
step down voltage for the BBB
cr_002.zip
the BBB