About this Blog

This blog is an engineering log book; for me to record the progress on my many projects and hopefully to inspire you.

Some projects do not get off the ground, they remain as interesting thoughts, a select few get some work done on them, even fewer get close to completion, and none get completed because unfortunately I subscribe to the theory: "If something ain't broke then it doesn't have enough features". If you'd like to collaborate on some work to get something to a useable state then send me some communications.

Being a blog, posts are listed in chronological order. However I usually have multiple projects on the go and will try to post some of my earlier work. With this in mind I'll try to add labels to each post so all posts relevant to one project can be easily extracted.

Enjoy and happy hacking.

Friday, August 29, 2008

It's Alive!


LEDs are a flashing. How exciting! Nothing gets a hardware engineer going like a couple of flashing LEDs. It symbolises success. Half the battle is won when you can program a piece of hardware to flash some LEDs. It means that you:
  1. Soldered the major components correctly,
  2. Have a working power supply,
  3. Have a tool chain for compiling programs for the hardware,
  4. Have a method for downloading the code to the hardware.
So I removed the 8MHz resonator connected to pins 2 and 3, not needed since the PIC has an internal RC oscillator. I soldered two LED resistor pairs between ground and pins 2 and 3 respectively. I then grabbed some assembly code from this site, and modified it to output to the two LEDs alternately. It is listed here:

; An LED Blinker

list p=12f675
include "p12f675.inc"
__CONFIG _CPD_OFF & _CP_OFF & _BODEN_OFF & _MCLRE_OFF &_PWRTE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT

small_delay_tmp equ 0x20
long_delay_tmp equ 0x21

goto main

small_delay:
movlw 0xff
movwf small_delay_tmp
small_delay_L1:
decfsz small_delay_tmp, F
goto small_delay_L1
return

; ----------------------------
; W contains count on entry.
; Store it in a temp variable.
; Keep on decrementing and
; calling small_delay
; ----------------------------

long_delay:
movwf long_delay_tmp
long_delay_L1:
call small_delay
decfsz long_delay_tmp, F
goto long_delay_L1
return

; ----------------------------
; The main LED blinker
; ----------------------------

main:

bcf STATUS, RP0
clrf GPIO
movlw 0x7
movwf CMCON ; disable comparator
bsf STATUS, RP0
movlw 0x0
movwf TRISIO ; All pins outputs
bcf STATUS, RP0

infinite:
bcf GPIO, GP5
bsf GPIO, GP4
movlw 0xFF
call long_delay
bsf GPIO, GP5
bcf GPIO, GP4
movlw 0xFF
call long_delay
goto infinite

end

I assembled it through piklab with gpasm from gputils. I then downloaded it through the ICD2 programmer again using piklab, configured so that the board is powered through the ICD2 (it doesn't seem to work otherwise). Amazingly the LED's flash, just like they are supposed to. Yay.

I'm not a fan of programming in assembler, so I'm going to try a couple of C compilers like SDCC. Unfortunately the PIC12F675 has only 1 kwords (1 word = 14 bits = 1 opcode) of program space, so to getting a C program to fit maybe a challenge. But why not try.

Programming Successfull!

So I spent a morning trying to get the programmer to connect to the PIC and remove the code protection.
After trying a few different default devices, the programmer (MPLAB ICD 2) successfully read the device identifier word. The PIC is a 12F675, datasheet and info. So now it knows what it is dealing with.

The remainder of the time was spent trying to get the damned programmer to erase the chip. An erasure would apparently work but a blank-check failed. So how about changing the configuration word (which has bits for code protection), can't do that either. So after much googling I found the problem, detailed here and here. In short, I think that the program already on the PIC was beginning to execute and messing with the programmer clock input. The output drivers of the ICD2 programmer arn't strong enough to over power the PIC and get it to program. So you have to get it into programming mode before it starts up and set pin 6 to an output. I achieved this by powering the PIC from the programmer (at 5V) instead of externally powered though the 3.3V regulator. Another option would be to disconnect the external oscillator, thus preventing the program from running.

So after that I managed to successfully erase the PIC. Yay! And I can reprogram the configuration byte. Note: I got a warning that the ICD2 programmer doesn't support programming with an internal oscillator and the MCLR pin set to a digital input. Probably to avoid the same situation as above.

Thursday, August 21, 2008

Some hurdles

So the PIC has no spare pins. Therefore to get a single wire serial bus to the device we must use the existing input wire and pin. The most common one wire bus is that of Dallas semiconductors and their 1-wire bus. No point reinventing the wheel (well not yet) so I plan to implement it on the PIC.

The 1-wire bus works by the master or slave device pulling the bus low for varying amounts of time to communicate 1's and 0's. No clock is required as each device is assumed to have a relatively stable clock source.

While reading the PIC datasheets I discovered a problems that will make the 1-wire bus difficult to implement. Pin-4, the one connected to the control wire has no output driver. It is an input only pin. This makes it impossible to pull the bus low.

Ok! So two options here. Put in a more modern micro-controller without these restrictions, like the Atmel ATtiny range. Unfortunately the power pins are not the same as the PIC - so messy rewiring needed.

The second is to change the pin. But there are no spare pins. Well actually the PIC has an internal RC oscillator, so the external 8MHz resonator isn't required. Yay two extra pins. One for the 1-wire bus and one for an LED too :).

Ofcourse this all depends on if I can actually reprogram the PIC.

Wednesday, August 20, 2008

Servo has a PIC, Can we connect to it?

I've identified the servo chip as a 12-series PIC microcontroller. The next question is can I connect an in-circuit programmer to it? I've borrowed a MPLAB ICD2 USB programmer from the resident PIC guru in my department. Cheers Phil. I wired it up as shown below and fired up LPLAB (MPLAB for linux).

Success! I can read the configuration fuses on the device. As suspected the code protection bits are set. The next thing to do is to try and write a progam to the device. I'm not sure if it is possible as some PICs are made with one-time programmable memory (not flash).

What's Inside the MG995 Servo?

The servo of choice (MG995) is the cheapest high torque (~15 kg/cm) servo that seems to be available world wide (at least it used to be). There is also a big brother servo (~20 kg/cm) that comes in Jumbo size and with nylon gears). I believe they are an OEM servo made in china like all cheap hardware. They are traded under a number of names, commonly Tower Pro.

Now lets break it open and work out what the nitty gritty bits inside are. The servos are labeled as "digi", which some take to mean digital. There are discussions on RC forums about these servos and if they are actually digital and how good they are. Apparently digital servos are better - better holding torque, less dead band and more responsive. The forum concensus was that they wern't digital (because digital servo's should be expensive). I'm not into my RC vehicles so I don't know much about servos, but I am a trained electronic engineer. As we shall soon see these servos are in fact digital (and i'd suggest that analogue servos would be more expensive).

Inspecting the circuit board inside we find:
  • three SOIC-8 ICs (5 in the big brother) which have had their marking removed (thanks Mr Manufacturer guy),
  • a couple of electrolytic capacitors,
  • some surface mount capacitors and resistors,
  • an 8MHz ceramic resonator,
  • a couple of transistors,
  • a 3.3V linear voltage regulator.
All but one of the SOIC-8 packages, (those next to the motor connections) are MOSFETs two N types and two P types in a full H Bridge configuration. On the MG995 board the two chips appear to be something like an IRF7309, housing a pair on N an P type MOSFETs, making a half bridge each.

The transistors provide the inverted full supply voltage drive signals to the P-type MOSFETs.

The final component of question is the 'contol' IC. In an attempt to protect the design the top of the IC has been scraped to remove the markings. I suspect the IC is a microcontroller.

The micro's pins are connected to:
Pin 1. VCC
Pin 2. Oscillator
Pin 3. Oscillator
Pin 4. H-bridge control
Pin 5. Servo's PWM control input wire
Pin 6. H-bridge control
Pin 7. Potentiometer input (ADC?)
Pin 8. GND

The micro is probably a PIC, since they are cheap and well known. After a bit of internet searching the pin-out matches the 8-pin microcontrollers of the 12-series PICs. The PIC12F510 being the most likely.

Truly Digital Servo Project

So I have these servos that I've used for a couple of projects. They are labeled "Tower Pro MG995". They are high torque (~15 kg/cm) servos with ball bearings and metal gears - perfect for robotics. Best of all they are cheap, I've seen them on ebay for < 10 USD, shipped from Hong Kong. They are also often re-branded by RC hobby-shops, a typical example is from rcnz.com here in Christchurch, NZ.

The control of RC servos in robotics projects is an often discussed problem, and it is fairly easy to provide the pulse width control signal from a microcontroller. There are plenty of websites discussing this. One thing that they don't tell you is that often they can be updated at more than the standard 50Hz, I have successfully run the MG995 servos at 60Hz (to match the 30 fps frame rate of a webcam).

However this PWM control is a bit of a drag. What if I want:
  • lots of servos in my system - requires lots of control signals.
  • feedback of where the servo actually is - have to add an extra wire to the internal potentiometer and read with an ADC.
  • control over the velocity profile of the servo's stroke.
The solution is to hack the internal control of the servo. Have a look at the openservo.com project where they have developed completly new electronic internals for standard servos. They seem to have done a very nice job but the 37 USD is a little steep for me. I may try and leverage some of their code though.

So what do I want?
  1. A bidirectional serial communication protocol - using a single wire, preferably on a bus system.
  2. A better control system - able to be given not only a position set-point but a velocity set-point. So looking at a state-space control system, with progammable gains to allow the control to be matched to the dynamics of the system it is connected to. Maybe even with some system identification or machine learning thrown in.
  3. Use a minimum of extra-parts. Because I am cheap and being in NZ makes anything but the simplest of parts difficut to obtain without a $50 shipping charge.