tag:blogger.com,1999:blog-591022544089978072024-03-14T23:30:55.565+13:00Will's Projects: Just for Procrastination's SakeWillhttp://www.blogger.com/profile/00572847938669990531noreply@blogger.comBlogger12125tag:blogger.com,1999:blog-59102254408997807.post-56443693815154575282009-09-24T11:10:00.003+12:002009-09-24T11:30:28.247+12:00Naming components in software? - Think about it!If you are writing a piece of code, especially for other peoples use, think about how you name it. Does it make sense? I have just wasted several hours chasing a bug in some VHDL for an Altera Cyclone III. I want to force the use of carry chains; to inform the synthisizer, pass the signals through a CARRY_SUM buffer that has the ports (Sin, Cin, Sout, Cout). There are a few rules that must be followed for the input logic functions of the signals.<br />rant begin<br /><em>Why did the engineer who constructed the CARRY_SUM buffer, put the ports in the opposite order; sum then carry. This engineer has single handedly wasted three hours of my life and I shudder to think how many other people have had the same problem</em>.<br />end rant;<br />Unfortunately this is set in stone now, no way to change it, here to annoy me forever. I've posted this in the hope that it will have saved you some precious time, because I couldn't find the solution anywhere else on the interwebs, probably because it makes you feel stupid when you do find the issue and don't want to admit it, hence the rant (it wasn't my fault).Willhttp://www.blogger.com/profile/00572847938669990531noreply@blogger.com0tag:blogger.com,1999:blog-59102254408997807.post-52988410812892919002009-04-27T19:36:00.007+12:002009-04-28T13:14:15.983+12:00Compiling the physics abstraction layer (PAL) with the BULLET physics engine<blockquote></blockquote>So I have an aquatic robotics project I am working on where I want to build a physics simulation for testing my control code. The robot itself is quite large and requires a large amount of space to operate in, i.e., open ocean and is currently in another city. This all makes testing and experimentation difficult. Therefore I am going to build a physics simulation that will emulate the robot on my laptop so I can do development at my leisure, and without getting water and sand in my beautiful laptop.<br /><br />So to start with I need to select a physics engine and compile it for my computer running Ubuntu Jaunty 9.04 64-bit. I have chosen to use the <a href="http://www.adrianboeing.com/pal/index.html">Physics Abstraction Layer (PAL)</a> since it looks relatively easy to use and includes some buoyancy functionality (which I intend to improve). It requires an actual physics engine back end, there are <a href="http://www.adrianboeing.com/pal/engines.html">many to choose from</a> such as ODE, Tomahawk, Box2D, .... I have chosen the <a href="http://www.bulletphysics.com">BULLET physics engine</a>.<br /><br />Now to set up the programming environment. How to compile and build PAL physics abstraction layer with the BULLET physics engine on Linux. The lines starting with a $ are to be executed on the command line.<br /><br />Get the Subversion source control client (svn):<br /><blockquote>$ sudo apt-get install subversion</blockquote>Checkout read-only copies of PAL and BULLET from svn:<br /><code></code><blockquote>$ svn co https://pal.svn.sourceforge.net/svnroot/pal/pal pal<br />$ svn checkout http://bullet.googlecode.com/svn/trunk/ bullet-read-only</blockquote>Get some of their dependencies:<br /><blockquote>$ sudo apt-get install freeglut3 freeglut3-dev cmake g++ cmake cmake-gui libsdl1.2-dev<br /></blockquote><span style="font-weight: bold;">Compile BULLET.</span><br /><blockquote>$ cd bullet-read-only</blockquote>Edit install.sh, replacing all Window's line endings (\r\n) with UNIX line endings (\n)<br /><blockquote>$ gedit install.sh &<br />Menu->Search->Replace, Search for \r\n, Replace with \n, click Find. Save, Quit.<br /></blockquote><blockquote>$ ./autogen</blockquote>If you have a multicore CPU then include the --enable-multithreaded option. It may give you better real-time performance.<br /><blockquote>$ ./configure --enable-multithreaded</blockquote><blockquote></blockquote>Compile using make.<br /><blockquote>$ make -j 2</blockquote>The -j 2 option tells make to do two jobs at once, i.e., use two CPU cores.<br />Install the Bullet libraries to /usr/local/lib/ and the Header files to /usr/local/include/bullet/<br /><blockquote>$ sudo make install<br /></blockquote>I had to manually copy the btActionInterface.h file to get PAL to compile, it appears it was left out of the install script.<br /><blockquote>$ sudo cp src/BulletDynamics/Dynamics/btActionInterface.h /usr/local/include/bullet/BulletDynamics/Dynamics/<br /></blockquote><span style="font-weight: bold;">Compile PAL.</span><br />Do not use the premake instructions for building PAL. I believe they are old. Use the Cmake system instead.<br /><blockquote>$ cd ../pal/</blockquote>Open the Cmake GUI<br /><blockquote>$ cmake-gui &<br /></blockquote>Enter the source and build directories at the top to the current directory (pal). The window below will list a bunch of variables. Select the tick box for PAL_BUILD_BULLET. Click "Configure". A window will show up. Select the default Unix make file option.<br /><br />Some more variables will be shown in the main window.<br /><ol><li>Set the BULLET_SINGLE_THREADED if you didn't build the multi-threaded version before.<br /></li><li>Fix the BULLET_INCLUDE_DIR -> /usr/local/include/bullet and the<br /></li><li>BULLET_LIBRARY_??? variables -> /usr/local/lib/lib???.so if they haven't been found.<br /></li><li>Change from simple view to advanced view and find the CMAKE_CXX_FLAGS variable and add -fPIC to it.</li></ol>Click Configure again. Hopefully there won't be any errors in the bottom window. If so try fix them.<br /><br />Click Generate. This will setup the project for you.<br /><br />Now make a few quick edits to get the demo to work. In pal/Config.h change the default engine from "BULLET" to "Bullet". In pal/example/begin.cpp change line 7 from PF->LoadPALfromDLL(); to PF->LoadPALfromDLL("/usr/local/lib/"); so it know's where to find the Bullet physics libraries.<br /><br />Now compile it.<br /><blockquote>$ make -j 2</blockquote>And install it.<br /><blockquote>$ sudo make install</blockquote>Tell the operating system about the new libraries.<br /><blockquote>$ sudo ldconfig</blockquote>Now we should be able to test the demo/test program. It has been compiled into the bin/ directory. Run it.<br /><blockquote>$ bin/palbeginner</blockquote>Should get output like:<br /><blockquote>Found dll 'liblibpal_bullet.so'<br />Found dll 'libbulletmultithreaded.so'<br />Found dll 'libbulletcollision.so'<br />Found dll 'libbulletdynamics.so'<br />Found dll 'libbulletmath.so'<br />Found dll 'libbulletsoftbody.so'<br />Physics:0x16e0840<br />Current box position is 1.49902 at time 0.01<br />Current box position is 1.49706 at time 0.02<br />Current box position is 1.49412 at time 0.03</blockquote>Fin.Willhttp://www.blogger.com/profile/00572847938669990531noreply@blogger.com3tag:blogger.com,1999:blog-59102254408997807.post-54369948042644559692008-10-15T08:10:00.001+13:002008-10-15T09:18:56.615+13:00Waving Hello WorldWe have servo action as can be seen in the video above. I have written some code to read the <a href="http://en.wikipedia.org/wiki/Analog-to-digital_converter">ADC</a>, calculate a <a href="http://en.wikipedia.org/wiki/PID_control">PID control</a> and provide a <a href="http://en.wikipedia.org/wiki/Pulse-width_modulation">PWM</a> signal to the motor. This all comes together to move the position read by the ADC to the set-point, which is moved backwards and forwards to make the servo wave. This is all done with 8-bit integers, however the ADC gives a 10-bit result, so next task will be to make it work with 16-bit integers - giving it 4-times the accuracy.<br /><br />I've had a few hiccups along the way.<br />The first was a problem with the piklab-prog program that loads the PIC through the ICD2 programmer. In short it was writing the contents of the last memory address 0x3FF(the oscillator calibration word) back to the memory location 0xFF, overwriting what was there. So I filed a <a href="http://sourceforge.net/tracker/index.php?func=detail&aid=2129632&group_id=138852&atid=743140">bug report</a> and reluctantly moved development to a windows machine.<br /><br />The second is choosing a C compiler for the PIC. <a href="http://microchip.htsoft.com/">Hitech</a> is a commertial compiler company that write compilers for the PIC. They seem like they should work well. They provide a free compiler PICC lite, but this doesn't do any optimisation - you have to pay for that. Buy you can use a 45 day trial of the optimisang standard version PICC std. It is also available for linux which is nice.<br /><br />Third problem is one that had me bamboozled for a couple of days. I was working on the PWM <a href="http://en.wikipedia.org/wiki/H-bridge">H-bridge</a> control. The left side is controlled by one GPIO1 and the right by GPIO2. The motor would spin fine in one direction but not in the other and causing the MOSFETS to heat up quickly. Having a look at the signals on an oscilloscope revealed that when GPIO1 was written high, it would go high for one instruction cycle but not stay high. This had the effect of making the mosfet switch on and off very quickly and hence the heat. After talking to Phil at uni he suggested that I was writing to the second pin too quickly (which I was - in the next instruction in fact). The problem is that the PIC operates with a read of the port, modification of the pins, and a write back. The read of the next instruction occurs just after the write of the last instruction. The write is delayed by the capcitance on the pin or other factors so the read of the port (which read the values of the pins) got the wrong value (one without the recently modified pin). This is called a <a href="http://en.wikipedia.org/wiki/Hazard_%28computer_architecture%29">RAW (Read after Write) hazard</a>. To fix this you need to do something in between or modify both at the same time.<br /><br />And finally I'll end with the question of using a <a href="http://en.wikipedia.org/wiki/Sigma-delta_modulation">sigma-delta</a> modulated output for control? Since the PWM at best runs at only 100Hz, not giving very precise control of the motor, maybe a sigma-delta type control would be better. It would have a "variable frequency" higher than 100Hz, fast response to a change in the servo position. It would also be smoother on the powersupply with several servos on the same bus with synchronised PWM.Willhttp://www.blogger.com/profile/00572847938669990531noreply@blogger.com0tag:blogger.com,1999:blog-59102254408997807.post-21503384041220096632008-09-15T20:32:00.003+12:002008-09-15T20:57:13.835+12:00Time PiecesI have a little fascination with time pieces, not your regular clocks though, but interesting ways to display the time. Every now and then I think of a new idea (or find one on the net) that I think would be cool to have sitting on my desk.<br /><br /><span style="font-weight: bold;">The Nixie clock</span>. I have a bunch of nixie tubes that i scavenged from a 1960's calculator. A nixie tube is what ws used for electronic displays before the 7-segment led came along. They are neon lights with cathodes in the shape of the numbers 0-9. When you apply ~200V between the cathode and annode the neon glows an awesome orange colour around the cathode. The difficulty with this project is the high voltages required.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.nixieclock.net/images/v400/high_resolution/nixie_clock_h3.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://www.nixieclock.net/images/v400/high_resolution/nixie_clock_h3.jpg" alt="" border="0" /></a><br /><br /><span style="font-weight: bold;">The Binary Clock</span>. Simply six columns of upto 4 led's that light up with binary numbers. Simple, but you have to be a bit of a geek to read and appreciate it.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.geekalerts.com/u/designer-binary-clock.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px;" src="http://www.geekalerts.com/u/designer-binary-clock.jpg" alt="" border="0" /></a><br /><span style="font-weight: bold;">Volumetric Display Clock</span>. A 5x5x5 cube of RGB leds. Can display alot of cool patterns on it but also the time in a number of ways.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.electronicsinfoline.com/New/img/news/200806/3920_0.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px;" src="http://www.electronicsinfoline.com/New/img/news/200806/3920_0.jpg" alt="" border="0" /></a><span style="font-weight: bold;">Multi-meter clock</span>. And my latest idea, have a microcontroller generate three voltages that extend to three test points labeled Hours, minutes and seconds. By probing with a multimeter you can discover the time.<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.dansdata.com/images/caselight/multimeter440.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 157px; height: 193px;" src="http://www.dansdata.com/images/caselight/multimeter440.jpg" alt="" border="0" /></a>Willhttp://www.blogger.com/profile/00572847938669990531noreply@blogger.com0tag:blogger.com,1999:blog-59102254408997807.post-9351179877489248602008-09-09T13:51:00.005+12:002008-10-10T09:56:19.732+13:00Software Plan - First RunMinimum specifications:<br /><ul><li>Use the existing hardware.</li><li>Run at 4MHz = 1MIPS on the internal RC oscillator to free up two extra pins.</li><li>Servo communications,<br /></li><ul><li>Bit bash a one-wire serial communications protocol,</li><ul><li>based on dallas 1-wire bus?</li></ul><li>Bit bash a two wire bus (maybe easier),</li><ul><li>I2C.</li></ul><li>Traditional servo pulse width command.<br /></li></ul><li>Each Servo individually addressable,</li><ul><li>255 unique addresses 0x00 - 0xFE,<br /></li><li>one broadcast address 0xFF.</li></ul><li>Servo action - position control,</li><ul><li>PID controller,</li><ul><li>Adjustable P, I and D gains.</li></ul><li>Other controller (LQR?).<br /></li><li>Dead band adjustment.<br /></li></ul><li>PWM power control for motor.</li><li>Debug LED(s).</li><li>Store configuration in EEPROM (128 bytes),</li><ul><li>Address.</li><li>Controller gains.</li><li>Control limits,</li><ul><li>Position extremes.</li><li>Torque\Current extremes.<br /></li></ul><li>Home Position.<br /></li></ul></ul>Optional features:<br /><ul><li>Current sensing,</li><ul><li>additional current sensing amp hardware required.</li><li>use additional ADC pin (GP4).</li></ul><li>Constant torque controller.</li></ul>Design Overview:<br />At startup:<br /><ol><li>Load the configuration data from EEPROM data memory into RAM.</li><li>Configure device.</li><ol><li>GPIO, GP1 and GP2 output (H-bridge).</li><li>GPIO, GP4 and GP5 (comms).<br /></li><li>ADC, GP0 input (Pot).<br /></li><li>TIMER0 (8bit, 1MHz, prescaler 1,2,4,8,16,32,64,128,256) for PWM.<br /></li><li>TIMER1 (16bit, 1MHz, prescaler 1,2,4,8) for Comms.<br /></li></ol><li>If startup bit START_CONTROL set then initialise control to "home position", else disable motor.</li><li>Initialise communications protocol, begin listening for address.<br /></li></ol>Willhttp://www.blogger.com/profile/00572847938669990531noreply@blogger.com0tag:blogger.com,1999:blog-59102254408997807.post-42038157927350677902008-09-05T15:51:00.003+12:002008-09-05T16:36:06.033+12:00Series Hybrid Electric Tandem BicycleSo I'm going to take a ride on the alternative transport band wagon with this idea. My girlfriend and I try and cycle most places, unfortunately she is about half my size and I'm twice as fast as her. Solution: a tandem bicycle. Only she worries that she won't be able to contribute to the propulsion because we are so mismatched, I pedal too fast or use a different gear than she would use or something. So I thought - you need independent drive trains. And of course, being an electrical engineer I turn to electronics to solve my problem.<br /><br />Why not, instead of the pedals driving a gear set, have them coupled to a low speed generator. Then from each pedal gen-set combine the power produced using a couple of power electronic converters to match the voltages onto a common DC bus. From there a third power-converter could run a heafty hub motor at the rear wheel (and the front too). A fourth converter could be used to attach a battery to the system and provide energy storage absorbed from excess human effort and regenerative braking and depleted for use uphill and takeoff.<br /><br />The pedal generators could be controlled to provide a constant cadence and torque, individually adjustable to suit the cyclists. One problem is that the RPM is quite low ~ 60-100 rpm. Since the voltage generated is roughly proportional to the speed of the generator (change of flux inside the generator windings) a multi-pole machine should be used (more than the usual two to four). The torque at the generator shaft is proportional to the current.<br /><br />One final benefit to a series hybrid bike. There is no dirty chain or temperamental derailer to deal with. Just simple, maintenance-free and clean electrons.<br /><br />It's unlikely that i'll get around to building this. However I have spoken to my supervising lecturer and he is going to offer it as a final year engineering project next year. So I may still get to ride it.Willhttp://www.blogger.com/profile/00572847938669990531noreply@blogger.com0tag:blogger.com,1999:blog-59102254408997807.post-72169087916768567632008-08-29T22:13:00.005+12:002008-08-29T22:57:37.423+12:00It's Alive!<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjywYVcxg0spvRxCOyyTtieS5adkZ1tHT1LR63UiZI8aLyQiw8A1Szmenqj6B9roc1SW8ZFYBdyceszT3WeD7yiWZH7yBbVOSEtaUlDQzm30gdAEpFXkTRTTn27ZH6tFvFKpKNjwW_zHA/s1600-h/LEDsFlashing.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjywYVcxg0spvRxCOyyTtieS5adkZ1tHT1LR63UiZI8aLyQiw8A1Szmenqj6B9roc1SW8ZFYBdyceszT3WeD7yiWZH7yBbVOSEtaUlDQzm30gdAEpFXkTRTTn27ZH6tFvFKpKNjwW_zHA/s320/LEDsFlashing.jpg" alt="" id="BLOGGER_PHOTO_ID_5239890973733522642" border="0" /></a><br /><div style="text-align: justify;">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:<br /></div><ol style="text-align: justify;"><li>Soldered the major components correctly,</li><li>Have a working power supply,</li><li>Have a tool chain for compiling programs for the hardware,</li><li>Have a method for downloading the code to the hardware.</li></ol><div style="text-align: justify;">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 <a href="http://pramode.net/pic/12f675.html">this site</a>, and modified it to output to the two LEDs alternately. It is listed here:<br /></div><br /><div style="text-align: justify;"><span style=";font-family:courier new;font-size:85%;" >; An LED Blinker</span><span style="font-size:85%;"><br /><br /></span><span style=";font-family:courier new;font-size:85%;" > list p=12f675</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > include "p12f675.inc"</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > __CONFIG _CPD_OFF & _CP_OFF & _BODEN_OFF & _MCLRE_OFF &_PWRTE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT</span><span style="font-size:85%;"><br /><br /></span><span style=";font-family:courier new;font-size:85%;" >small_delay_tmp equ 0x20</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" >long_delay_tmp equ 0x21</span><span style="font-size:85%;"><br /><br /></span><span style=";font-family:courier new;font-size:85%;" > goto main</span><span style="font-size:85%;"><br /><br /></span><span style=";font-family:courier new;font-size:85%;" >small_delay:</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > movlw 0xff</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > movwf small_delay_tmp</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" >small_delay_L1:</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > decfsz small_delay_tmp, F</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > goto small_delay_L1</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > return</span><span style="font-size:85%;"><br /><br /></span><span style=";font-family:courier new;font-size:85%;" >; ----------------------------</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" >; W contains count on entry.</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" >; Store it in a temp variable.</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" >; Keep on decrementing and</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" >; calling small_delay</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" >; ----------------------------</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > </span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" >long_delay:</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > movwf long_delay_tmp</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" >long_delay_L1:</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > call small_delay</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > decfsz long_delay_tmp, F</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > goto long_delay_L1</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > return</span><span style="font-size:85%;"><br /><br /></span><span style=";font-family:courier new;font-size:85%;" >; ----------------------------</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" >; The main LED blinker</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" >; ----------------------------</span><span style="font-size:85%;"><br /><br /></span><span style=";font-family:courier new;font-size:85%;" >main:</span><span style="font-size:85%;"><br /><br /></span><span style=";font-family:courier new;font-size:85%;" > bcf STATUS, RP0</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > clrf GPIO</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > movlw 0x7</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > movwf CMCON ; disable comparator</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > bsf STATUS, RP0</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > movlw 0x0</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > movwf TRISIO ; All pins outputs</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > bcf STATUS, RP0</span><span style="font-size:85%;"><br /><br /></span><span style=";font-family:courier new;font-size:85%;" >infinite:</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > bcf GPIO, GP5</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > bsf GPIO, GP4</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > movlw 0xFF</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > call long_delay</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > bsf GPIO, GP5</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > bcf GPIO, GP4</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > movlw 0xFF</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > call long_delay</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > goto infinite</span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > </span><span style="font-size:85%;"><br /></span><span style=";font-family:courier new;font-size:85%;" > end</span><span style="font-size:85%;"><br /></span></div><br /><div style="text-align: justify;">I assembled it through <a href="http://piklab.sourceforge.net/">piklab</a> with gpasm from <a href="http://gputils.sourceforge.net/">gputils</a>. I then downloaded it through the ICD2 programmer again using <a href="http://piklab.sourceforge.net/">piklab</a>, 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.<br /><br />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.</div>Willhttp://www.blogger.com/profile/00572847938669990531noreply@blogger.com2tag:blogger.com,1999:blog-59102254408997807.post-20528779567964491272008-08-29T11:56:00.004+12:002008-08-29T16:42:00.022+12:00Programming Successfull!So I spent a morning trying to get the programmer to connect to the PIC and remove the code protection.<br />After trying a few different default devices, the programmer (MPLAB ICD 2) successfully read the device identifier word. The PIC is a <span style="font-weight: bold;">12F675</span>, <a href="http://ww1.microchip.com/downloads/en/DeviceDoc/41190E.pdf">datasheet</a> and <a href="http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en010114">info</a>. So now it knows what it is dealing with.<br /><br />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 <a href="http://forum.microchip.com/printable.aspx?m=350645">here</a> and <a href="http://forum.microchip.com/tm.aspx?m=303686&mpage=2&key=&#308594">here</a>. 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.<br /><br />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.<br /><a href="http://forum.microchip.com/printable.aspx?m=350645"> </a>Willhttp://www.blogger.com/profile/00572847938669990531noreply@blogger.com0tag:blogger.com,1999:blog-59102254408997807.post-32695799041007344612008-08-21T12:23:00.005+12:002008-08-29T12:23:01.967+12:00Some hurdlesSo 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.<br /><br />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.<br /><br />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.<br /><br />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.<br /><br />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 :). <br /><br />Ofcourse this all depends on if I can actually reprogram the PIC.Willhttp://www.blogger.com/profile/00572847938669990531noreply@blogger.com0tag:blogger.com,1999:blog-59102254408997807.post-89580075659894080612008-08-20T21:05:00.003+12:002008-08-21T12:23:27.687+12:00Servo 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).<br /><br />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).Willhttp://www.blogger.com/profile/00572847938669990531noreply@blogger.com0tag:blogger.com,1999:blog-59102254408997807.post-44538866788773287612008-08-20T14:59:00.005+12:002008-09-07T22:33:58.633+12:00What'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.<br /><br />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).<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSXg9_rwTthvi3t-HzzZQaWtxL3fZAGHv0M6BMKjee2maNiCktWnXOVkX9ihTyanBEfesZv5OXjH1jhMl4_ItI3xavkdxMedXAXA7b3vuuRMU9VIt_KXseD4KqOrgXT1Ai35XO6j-TnQ/s1600-h/MG995-internals.JPG"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSXg9_rwTthvi3t-HzzZQaWtxL3fZAGHv0M6BMKjee2maNiCktWnXOVkX9ihTyanBEfesZv5OXjH1jhMl4_ItI3xavkdxMedXAXA7b3vuuRMU9VIt_KXseD4KqOrgXT1Ai35XO6j-TnQ/s320/MG995-internals.JPG" alt="" id="BLOGGER_PHOTO_ID_5243098943694385650" border="0" /></a>Inspecting the circuit board inside we find:<br /><ul><li>three SOIC-8 ICs (5 in the big brother) which have had their marking removed (thanks Mr Manufacturer guy),<br /></li><li>a couple of electrolytic capacitors,<br /></li><li>some surface mount capacitors and resistors,<br /></li><li>an 8MHz ceramic resonator,<br /></li><li>a couple of transistors,<br /></li><li>a 3.3V linear voltage regulator.</li></ul>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.<br /><br />The transistors provide the inverted full supply voltage drive signals to the P-type MOSFETs.<br /><br />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.<br /><br />The micro's pins are connected to:<br />Pin 1. VCC<br />Pin 2. Oscillator<br />Pin 3. Oscillator<br />Pin 4. H-bridge control<br />Pin 5. Servo's PWM control input wire<br />Pin 6. H-bridge control<br />Pin 7. Potentiometer input (ADC?)<br />Pin 8. GND<br /><br /><div style="text-align: left;">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.<br /></div>Willhttp://www.blogger.com/profile/00572847938669990531noreply@blogger.com0tag:blogger.com,1999:blog-59102254408997807.post-62383271761416962492008-08-20T12:52:00.002+12:002008-08-20T14:58:29.026+12:00Truly Digital Servo ProjectSo 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.<br /><br />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).<br /><br />However this PWM control is a bit of a drag. What if I want:<br /><ul><li>lots of servos in my system - requires lots of control signals.</li><li>feedback of where the servo actually is - have to add an extra wire to the internal potentiometer and read with an ADC.<br /></li><li>control over the velocity profile of the servo's stroke.<br /></li></ul>The solution is to hack the internal control of the servo. Have a look at the <a href="http://www.openservo.com">openservo.com</a> 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.<br /><br />So what do I want?<br /><ol><li>A bidirectional serial communication protocol - using a single wire, preferably on a bus system.</li><li>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.</li><li>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.</li></ol>Willhttp://www.blogger.com/profile/00572847938669990531noreply@blogger.com0