Wednesday 26 December 2012

Milling the first Cup

You may have seen the gcode i posted, it was looking great until i realized that the mill wasn't yetup to the job, the Z axis has about 2.5mm of backlash!!! that's just NASTY if your code makes this axis go up and down... really need to stop playing and attach a gas strut piston to hole up the head. get rid of the backlash, not too sure how that all works will have to find that web page that suggested it as a solution and double check what i am thinking.

So while i was setting up to cut the first of 24 coil cups for the magnetic bed i ran into a small electromechanical issue, the handle on the Z axis caught a wire which cause the loom to get pulled which in turn caught and pinched the Z stepper wires and proceeded to release the magic smoke that killed the axis' stepper driver. Not happy jan...

After i sorted that problem out i proceeded to attempt the first cut thats when i found the Z backlash to be bad, so i changed the code so it only drives the Z axis in the downward direction, making the backlash not a problem for now..

 I Loaded up the chuck with a 7mm 4 flute end mill cutter slapped a chunk of 25mm hex bar into the jaws of the dividing head and set the Z axis to be 16mm in SW and HW and hit play.. the results are below.

the gcode that's running in the above video is plunge 0.25 then spin then spin back then  repeat. today i have some new code that i wrote that will plunge as its rotating and not need to spin back to reset the axis.

I discovered that i really really need to mount the DRO scales permanently they have about 0.5mm of backlash in them.. i will replace the temporary double sided tape for screws.

in the video you cant quite see it but we jury-rigged an air blower up to clear the swarf from the job and spread it far and wide across the workshop..

we smashed a 7mm end cutter into a ball of brokenness when i was playing with some settings and spun the job in the chuck at a speed FAR FAR too fast the slider was reset between reboots and i forgot the defaults are still dangerous!... oh well another $5 on ebay.. i have more cutters to replace i have lunched a few while learning the limits of the mill, these cutters are dirt cheap so i dont mind..

I was meant to make the drive bolt for my printer as the first project but unfortunately i dont have the brass rod thats the right size for the job :( so i am keeping my self busy while i wait for the steel store to open :)

Tuesday 25 December 2012

Progress on the magnetic milling bed

While i wait to get the last belt for the Y Axis stepper, I want to make some more progress on the mill.

I am going to attempt to make 25 hexagonal coil cups, these are 15mm tall section of 25mm hex bar. I will take a length of hex bar that is 25mm across the flats and cut 25 sections 16mm long. once these are cut i will place each one in the jaws of the dividing head (which will be vertically mounted, that is,  it will turn in the same axis as the cutter turns.

I will then program by hand some Gcode that will lower the tool into the job 12mm deep as it rotates. this will cut a circular slot into the hex face of the job that will allow me to place a sewing machine bobbin into, this bobbin will have wire wound onto the coil, when placed in to the cup onto the center pin and the coil energized any bits of metal will be attracted to the cup and coil, with the coil is set in the cup with epoxy and each of the 25 cups welded into a flat bed i should be able to hold the job with the touch of a button on the UI. the holding force will be adjustable via a slider on the touchscreen.

the code to cut cups :)

%
G21
G90
; starting at 16mm need to get to 3mm, so 13mm of z travel in 0.25mm passes
; 13/0.25 = 52 layers to this program.

; this will mean when i turn the cups upside down get them welded i can then face that off
; to make the flat mounting surface, i then flip and repeat to make my flat working surface
; set the mill to the start position then start.

G1 Z15.75 F100          ; drop the cutter 0.25mm
G1 A360 F300            ; spin the job 360' slowly
G1 Z16 F1000             ; pull the cutter out of the job
G1 A0 F1000              ; spin the job back to the start postion
G1 Z15.75 F1000        ; drop the cutter back down ready for next pass

G1 Z15.5 F100           ; repeat
G1 A360 F300
G1 Z16 F1000
G1 A0 F1000
G1 Z15.5 F1000

G1 Z15.25 F100         ; and repeat some more
G1 A360 F300
G1 Z16 F1000
G1 A0 F1000
G1 Z15.25 F1000
.
.
.
.
.

G1 Z3.25 F100        ; more repeating
G1 A360 F300
G1 Z16 F1000
G1 A0 F1000
G1 Z3.25 F1000

G1 Z3 F100              ; done repeating
G1 A360 F300
G1 Z16 F1000
G1 A0 F1000
G1 Z3 F1000
G1 Z50                   ; job done pull cutter up to allow for next piece . should be able to just hit run between pieces.
%

i ended up using a spreadsheet application open office to write this code i found it easier that way as its repeated 52 times if i need to change a value now i just change the first block then the rest follow to match.

then i take these values and use a concatenate function to join them all for cutting and pasting to a text file.

I really need to find a application that can do this for me. ie write gcode for a dividing head.
i suppose if its not already done i could write something that takes a bunch of parameters and generates the gcode, this would probably result in a module for each type of operation like cut helix, drill hole patterns etc..

EMC Setup. Glade Vs pyvcp

Hands up all those who survived the end of the world :p

I have spent the last few days poking around EMC2 linuxcnc. For an Open source project this is Awesome, it has good documentation and good delivery of its end goal, control a machine and make it do our bidding.

I have been playing around making an UI that has all the functions i want, where i want them and working how i want them to work. So i read a bit of documentation and thought i had picked the path of least resistance, not really knowing what Glade was and having a little experience with python i went with the pyvcp option. this is great it allows you to do all sorts of things, control various parts of the machine, in my case a milling machine and dividing head. i went through the steps of setting up the parallel ports and defining pins to each hardware device i want to use.

Next i wanted to find some GUI interface that would allow me to control these hardware functions easily from a touchscreen. when i first created the custom vcp it was tacked onto the right hand edge of the existing UI window, this in theory is great makes life easy, in practice this is not so great for my setup, i am using a 800x600 LCD screen and i have a PCT touchscreen to match it, when the extra section of controls were added to the window it makes EMC's GUI go nuts. every time you click the mouse or touch the screen the page would jump between locating the top left corner of the window to the top left corner of the screen then next touch it would jump to show the bottom right of the window in the bottom right of the screen. this is not noticed if the window is smaller than your screen but if it is larger then you will see this problem. two solutions exist that i know of, use a higher screen res (not an option for me as i am hardware limited to 800x600), add the control panel as a second floating window and provide a way to switch between this and the original UI window.

i chose the second option, this works nice , the original UI is a little narrower than the screen so i anchored the new window to the top right of the screen and kept the original screen in the top left. this keeps a 1 inch section of screen that i can use to touch to swap between windows. i then populated the window with lots of big buttons and sliders that are nice to use in a touchscreen environment. i hear people screaming why not just use touchy.pyvcp interface that is supplied? please see the problem just above with the screen jumping around when the window is larger than 800x600. probably not the most efficient solution but it gets me to where i need to be. plus i have a few other features i wanted to add to the mix. and as it turns out its easy as pi to roll your own.

I added sliders for a grinding motor, coolant pump, work lamp brightness, spindle speed and jog speed. with these i added enable buttons, which i made latch with the classicladder PLC thats built into EMC, this was easy to do as i have learnt PLC programming a decade ago, even though i have never used it since it was easy to work out again all those classes in the basement of granville tafe came flooding back, my project was a railway level crossing, train sensors lights, bells, it was a great project.  the PLC is a very powerful tool it took me a little playing and looking at the examples to work out how the variables integrate with the UI and the HAL but i think i have three quarters of a clue now. I added jog buttons these buttons all work. I even programmed a home axis button with MDI commands :)

I was going great guns for a while. I stopped for some family time (ie Christmas) then came back to it. The last thing that i really wanted to setup was at the very least was a simple tool changer routine. My plan is to use a stepper connected to the 5th axis to rotate a carousel of tools at a set X,Y,Z location so the chuck could release and hold tools as they are presented to it. this is when i have hit a SOLID Brick wall. I should have read a bit more of the manual and the hardware integrators guide to see exactly what pyvcp can and cannot do (maybe i read it but didn't understand at the time that i need more features). i could write a massive PLC  ladder program to try and control the tool changer from that but it would be really hard and probably wont end up being doable.

I have come to the conclusion that i MUST use glade to get the control and program-ability i am going to require. this was a great learning experience and my efforts have not been wasted, i will use this setup until i make my tool changer.. then once i have the mechanical parts done come back to the UI.

while i am waiting to get my last toothed belt from my mates locked up workshop i have been thinking about what i can do to use my time and actually use the mill, while making the UI was great i want to get some chips flying. so i am going to try and make some progress on the mill in the fashion of the magnetic clamping bed. more next post.

Thursday 20 December 2012

Milling Cutters

If the impending Zombie apocalypse happens today this post is a little pointless :p but i came across a great website that supplies all sorts of milling cutters, even the exotic ones like tiny woodruff cutters.

As i need a cutter to cut my drive bolt for the printers extruder, i would really like to learn how to cut my own cutters, i have played a little and have come to the conclusion that i need to either make some sort of grinding tool with an indexing head/chuck.

I have nice shiny new dividing head that my mate built for me, so i am half way there. but as i am sure i have mentioned before that i am an impatient unit i was looking on the web at whats available. I came across www.harveytool.com and searching through their online catalog i found this cutter

Double angle woodruff cutter this tiny little cutter is the ideal profile for my hyeena bolt, 66108 is the one i think will do me. the measurements are all imperial so i will convert to metric so my brain can make sense of it.


D1                                        = 1/8th inch             = 3.175mm
Neck diameter                     = 1/16th inch            = 1.5875mm
(D1-Neck)/2 Shoulder size  = 1/32th inch           = 0.79375mm 
L2 Shoulder width               = 0.17in                   = 0.42mm
Shank Diam                         = 1/8th                      = 3.175mm
A angle of cut                      = 30'                         = 30'


looks like this guy is a little bit small to make my life easy. if i want to cut the teeth in one pass i need a cutter thats at least 3.5mm diameter, if use the next size up cutter 3/16 its 4.7625mm in diam. this cutter would be able to cut an entire tooth in one motion.  without needing to move along the shaft/gear/bolt. this larger cutter 66112 has a shoulder width of 0.5842mm at its widest. i had drawn my bolt to have a 1mm wide gap between the peaks of each tooth. so i will use the dividing head to turn the job while the cutter has made its initial groove. this will give me the option of cutting wider grooves as well as narrower grooves without having to buy two tools they are only $35ea.

so the more i think about whats required to make my own cutters i see that there is some really complex maths involved while this in it self is not too troubling it makes me think that the device that is required to cut cutters is rather complex. to cut the flutes on a straight cutter you need A,B,X,Y,Z this seems not too imposing until you add the word precision into the equation. if i want to be able to use cheap off the shelf grind wheels and stones i will have to be able to some how know what the diameter of the wheel or stone will be, if i can find a good diamond wheel i will be set as their diameter doesn't vary a great deal when compared to a carbide disc or stone. so i will need a way to touch the wheel to sense its cutting edge. this wont be too hard if use a micro switch.

thinking about the software side of things i would need to break it down into a series of passes.

1. Profile
      This will grind the side profile of the cutter, ie ball nose, woodruff, slot cutter etc.
2. Pluting
       This will grind the flutes into the cutter.



To grind the profile the cutting disc will be perpendicular to the rotating axis, that is if the tool steel blank is held along the X axis left to right. the cutter would rotate in the A axis and the grinding wheel will rotate in the Y axis at the same height as the center of the toolsteel. the grind stone would move in and out towards the rotating center of the toolsteel according to the profile required asnthe toolsteel rotates.

To grind the flutes the cutting disc/grind wheel will need to be pivoted in the B axis to the angle of the flute to be cut and offset to set the depth of cut, as the toolsteel is rotated the grinding disc will need to move along the X axis at the correct rate to make the screw/helix shape.

I theory this all sounds simple enough, write some gcode that makes the profile of the blank then write gcode that cuts the helix of the flutes. when it comes to practice it will be a different story, will post some screen grabs and explanations of how it will work soon.


Sunday 16 December 2012

Some Gcode

I couldn't help myself i had to see if i could write some gcode and see if it would do what i tell it.

what i did was first calculate the circumference of my blank 10mm rod. i then calculated how many teeth and grooves i can cut in to that surface. i worked out that if i have 1mm gaps and 0.75mm peaks i would end up with 17.5 teeth so i did the maths to even that up to 18 teeth. that gives me a 20' rotation between slices that will make my gaps 1mm and leave a peak of 0.74mm between the gaps.

the gcode to do this is specific to my cutter that i have made, it is a 1mm thick cutter with a 3.5mm diameter. if you were to think of a tiny T slot cutter then you are spot on..

G21                               #select metric mode
G91                               #select incremental referencing
G0 Y-19 F10                 # sets up cutter ready to eat metal

G0 Y7 F10                   # gets closer to the job
G0 Y3 F0.0005            # moves in for the cut.
G0 Y-10 F10                # move back from job
G0 A20 F10                 # rotates job 20' ready for next cut

G0 Y7 F10                   # and repeat 17 more times to cut all the teeth.
G0 Y3 F0.0005
G0 Y-10 F10
G0 A20 F10

G0 Y7 F10
G0 Y3 F0.0005
G0 Y-10 F10
G0 A20 F10

G0 Y7 F10
G0 Y3 F0.0005
G0 Y-10 F10
G0 A20 F10

G0 Y7 F10
G0 Y3 F0.0005
G0 Y-10 F10
G0 A20 F10

G0 Y7 F10
G0 Y3 F0.0005
G0 Y-10 F10
G0 A20 F10

G0 Y7 F10
G0 Y3 F0.0005
G0 Y-10 F10
G0 A20 F10

G0 Y7 F10
G0 Y3 F0.0005
G0 Y-10 F10
G0 A20 F10

G0 Y7 F10
G0 Y3 F0.0005
G0 Y-10 F10
G0 A20 F10

G0 Y7 F10
G0 Y3 F0.0005
G0 Y-10 F10
G0 A20 F10

G0 Y7 F10
G0 Y3 F0.0005
G0 Y-10 F10
G0 A20 F10

G0 Y7 F10
G0 Y3 F0.0005
G0 Y-10 F10
G0 A20 F10

G0 Y7 F10
G0 Y3 F0.0005
G0 Y-10 F10
G0 A20 F10

G0 Y7 F10
G0 Y3 F0.0005
G0 Y-10 F10
G0 A20 F10

G0 Y7 F10
G0 Y3 F0.0005
G0 Y-10 F10
G0 A20 F10

G0 Y7 F10
G0 Y3 F0.0005
G0 Y-10 F10
G0 A20 F10

G0 Y7 F10
G0 Y3 F0.0005
G0 Y-10 F10
G0 A20 F10

G0 Y7 F10
G0 Y3 F0.0005
G0 Y-10 F10
G0 A20 F10
%


there you have it rather simple isn't i will post some pictures of what i make and some screen grabs of what the part should look like and you can all have a look and laugh at how different the two are :).

oh also this gcode will only cut one of the three sections that i require for my printer. i do like to make things hard for myself :0

Progress on the Mill build

Its nearly Christmas,

My mate found time to finish off 90% of the dividing head ( YAY ). I rushed it home with the PC and controller box, attached a power plug that i had been putting off until i had a reason to. Then proceeded to install a copy of ECM running on Ubuntu 10.04 from a liveCD image to a USB key then onto the 4Gb CF card. the motherboard seems to be a little slow booting up so i may sink another $50 into the build and buy a 8GB sata SSD and liberate the processor..

Once I had the OS and EMC installed I Proceeded to attempt to configure EMC. this turned out to be in total a 2 day ordeal. first the problems were getting the LiveCD image to actually boot, just had to find a magical usb key and the right settings in the bios and standing on one foot with one eye closed :).

I purchased the Stepper interface quite a while ago and the exact user manual for my board so i started looking on ebay, i couldn't find the exact seller with the same unit. I did find several that looked the same, but when i downloaded the data sheets for them the pin maps just didn't line up properly, the 5 axis data sheet had the right title and said it was for the 5 axis model but the pin table only showed 4 axis, another had only 3 axis, then finally i found one that had all five axis labeled..

I ran the stepconf program to configure the stepper drivers as per the data sheet, but weird stuff happened, so then i looked at my cable that i have made to go between the par port and the stepper driver, turns out that this was rather wrong, so i turned the ends around about 5 times until i finally got the right orientation so pin 1 is connected to pin 1 and so on. i tested the results and yet another fail, not sure where the problem was i started testing, i grabbed a LED and jammed it in the end of the cable, then clicked on things in the gui and all the pins matched their functions. So then i figured i should probably check the pin functions on the stepper board.. this was a little difficult, i had to first work out which pins would make a led light up then try and work out what that led meant, in the end i managed to get each Axis spinning in both directions when commanded to, some of the axis were being difficult but got there in the end.

At this point in time i have all the Axis responding to the GUI buttons, i have calibrated the XYZ Axis' according to the numbers, leadscrews have 16TPI = 1.558mm/Revolution, 200 steps per rev on the steppers, 1:1 drive ratio and 2:1 microsteps. this results in 251.9steps/mm. for the Dividing head it has 200 steps per rev, 1:3 ratio, and 16:1 microsteps, resulting in 26.7 steps per degree, this should be fine enough for what i want to play with. I should be able to cut some gears and worms, but first on the list is a triple hyena bolt. Arcol from the reprap forums has designed a really nice drive bolt that grips the plastic really well and doesn't clog up, i have asked in the past if he could make me a custom one that has three sets of teeth but at the time it wasn't worth his time as he gets his bolts that he sells made in a workshop by real machinists if anyone is wondering what sort of bolt they should use see Arcol's blog.

Before i have even bolted all the bits on to the mill i already want to program it... I want to write some gcode that will cut my bolt :) there are a few parameters that i will have to get from the Mill itself for the code to be complete but i will write it anyway, have i mentioned before i am an impatient and impulsive sort of person...
next post some Gcode to cut a Drive bolt..


 here you can see the dividing head sitting on the X axis, my mate made me a Angle bracket to mount the head to the bed as shown above, or to have the head pointing up so you could drill or slot a gear as well as cut the teeth.
here you can see how chunky it is compared to the rest of the mill. we should have no bounce or flex when this is mounted in either position. hanging out the side of the bed there you can see the profile piece that is becoming T nuts :)

here is a close up of the belt and pulley. in testing i have done on the bench here this little chuck has some torque behind it. the steppers are 269 ounce with a 3:1 ratio on it that should come out at over 60netwons/meter. that could be more torque than on the other axis :)

Thursday 20 September 2012

1milli-second counter with 1ns resolution

To start with I am not too sure if this will work if it does i am still not sure if this will help me reach my goal. For my DIY GPR I need a way to count really really small time units. So i can determine how long the reflected radio wave have taken to reach an object bounce off it and return to my antenna.

 So I have devised a possible solution to solve my problem. what i have is a 1Ghz oscillator ASG-P-X-A-1.000GHZ, this device is $28au from digikey it has LVDS output which is nice for my first UHF PCB. coupled to that i have a MCA100EP016AFAG 8 bit counter capable of 2.2Ghz.

I started to lay the board out then i realized that if i make this board i will have spares as its a prototype for my GPR so i may use it somewhere else in the future if all goes well, so i changed the PCB from 50x50 to fit a arduino MEGA footprint. this would allow me to Hack on either an arduino MEGA or a MAX32. once i found the footprint of the MEGA (see my previous post) i noticed that i have Stacks of free space on the board so i thought about what else this counter might need.. i started with space for 16Mbytes of FLASH serial SPI memory, then i my attention moved to how i was going to trigger the counter to start and stop so i can read it at my pleasure as this counter will be configured as a single shot to avoid having to incorporate highspeed RAM to store results in, i figured a simple counter on the enable line might do the trick, so i have added a decade counter 744017and a  four element SR latch 74279.

As the Counter and oscillator are 3.3v devices this board really shouldn't be used on a mega, i will only use it with a MAX32 as they are a 3.3 volt board.

With the SR latch and the decade counter being stock standard 74 series logic chip i could replace these with any logic chip from that family. i have only wired the ground and power pins the others go to pads so they can be rats nested into any configuration that i may need in the future..

I also have a alternate Voltage regulator for 3.3v a stack of decoupling caps, the voltage regulator is either supplied off the arduino 5v rail or its own input header.the regulator accepts any 78xx SOT223 regulator that has a IN-GND-OUT pin footprint.

So the plan seems sound enough for now, i will spend $40 and get 10 of these boards made once i have laid out all the tracks. hopefully i will be able to get the oscillator running, the counter counting, then i can see about starting and stopping the counter with a signal. my plan is to use the SR latch to latch the enable pin to high (its active low) then when a ping is sent i release the counter to ... count :) then when a echo comes along we can stop it. read the time and reset everything and start again, this time we use the decade counter to miss/ignore the first echo and capture the second echo, this may require me to pre-seed the decade counter before i send a ping, but this board is so generic i can work that out while i wait for the oscillator and counter to arrive..





thats what i have laid out so far. just a few tracks here and there and a carefully placed ground plane and i should be good to send it off to the factory in china to be made..

I have picked my pins i hope carefully, so all the important information can be read and written in single word instructions, i have the first 8 bits of the 1Ghz counter on one port the next 12 bits are on another port and the preset data are on two ports of the PIC, this means some are side by side and others are spread across the PCB. the pins for the SPI flash chips are broken out so i can solder thwm to where ever i like. this is not the main purpose of the board so they will need to be rats nested to the MAX32 pins. you may notice that there are places for two variable resistors, for my initial purpose these pins are pulled high, but other oscillators use these pins to set the frequency, in case i find 1ns is not fine enough resolution i can simply change parts without needing fresh boards to be made or horrible hacks near the RFHF's in that area..  i will enclose the oscillator and support components under a tin can to keep the signal from radiating everywhere and potentially causing problems.

Tuesday 18 September 2012

Arduino Mega Hole Spacings

Found a useful link. I don't like eagle, as i use Altuim, so i was trying to find the hole spacing for the arduino clone Chipkit MAX32.

http://www.wayneandlayne.com/files/common/arduino_mega_drawing_5000x2642.png

also hosted on that site is the uno hole spacings. as i said i was looking for the chipkit max32 hole spacing, all you need is to add second row here and there and your done. enjoy.

Sunday 16 September 2012

Ground Penetrating Radar

At a loss with the compass my attention has wondered to a thought experiment regarding GPR or Ground Penetrating Radar.

I was asked a while ago by a friend if it was possible to build a GPR DIY style. At the time i thought no there is no way.. A few years have passed since and i thought i would revisit the idea.

So What is GPR. Its just like normal Aircraft Radar. Aircraft Radar works by sending out a radio wave or pulse and listening for the signal to bounce off and return. If you know the direction of where you sent the pulse and how long the pulse takes to return, if you measure the difference in the frequency of the echo you get the speed of the aircraft. look up the Doppler effect for the speed i wont go into that here as the ground has no speed.

So with GPR the same thing happens, only we send the pulse into the ground and wait for the reflections. as a Radio wave is just a light wave in a different band the distance traveled is the same as the speed of light. there should be a little shift in this value (according to my logic in my head) for when traveling through rock, soil, sand and water, but i haven't found this information on the net i may not need to worry about it as this device would be just a indicator of where you might find something, not a life or death situation.

Having a little search around on the internet I see that High frequencies don't travel well through solid objects, i found a note on a forum that said the signals with the best results for GPR are likely to be around 10Mhz to 100Mhz.  From playing around in the past i should be able to generate a pulse in that range and receive it with a pair of small antenna's. The hard part will be counting the time travel time of the pulse.


Lets define a few parameters.
Depth                : 30     Meters
Resolution (D)  :  < 1   Meter
Resolution (H)  :  < 1   Meter^2

Hardware

To work out what hardware will be required we need to do a little maths.. First the speed of Light is 299792358m/s. that means our pulse will travel 299792358 meters in one second. if we are to get <1m accuracy in the Depth Axis we will need to count really fast. Aircraft Radar has a lower resolution that we need, the planes are further away so the timing is easier with old hardware. if we are to have a range of 30 or so meters we will need to be able to count for

(30*2)/299792358     =   1 / 4996539.3 = 0.0000002 or 200ns      (*2 is because we need to time the reflection so 50 meters)

our Resolution will depend on how high we can count to. in 200ns. i don't know of too many MCU's that are capable of achieving the speeds this is looking like requiring. so lets do the maths and see.
eg.
if we can count to 4 in 200ns that will mean 60m/4  = 15m  / count.

in 200ns the pulse/wave will travel 60meters, if we want sub meter resolution we will need to break that 200ns into slots, 4 slots would = 15meters per slots. not very clear, clearer than a traditional metal detector. but not GPR worthy.

what if we can count to 256 in 200ns?
  60/256 = 0.2343m/count or 23cm so when we see i ping bounce back on the display, and it is actually at 1meter depth, our system may report it as being between 1.00m and 1.25m if its actually at 1.1meters depth the system may report it at a depth of between 1.0 and 1.25m. not to bad if you had to dig another foot or a foot less that's ok with me.

so to count to 256 in 200 nano seconds we need a clock of... 1.28Ghz.. ARGH!!!!
as i said i dont know of a MCU that will do this...

As a possible solution to the crazy clocking speeds I would need on a MCU what actually needs to happen at that rate is, when an echo is received we need to know the time. echo strength would be nice too, that would depend on the radio set used if that information is available. what we might be able to do is have a free running oscillator at 1.2Ghz that is fed to a 8bit counter, then when an echo is  read the count/time  is stopped and is latched out of the counter and presented to a user in a usable fashion.

This system will work for a the first echo. now the output i have seen on TV when these things are used on documentary films is a multiple echo report. that is their data uses multiple echos to create the map for interpretation..

Depending on what we want to use the GPR for this may be all that we need, to overcome this limitation my first solution is a simple one, have multiple (A)counters all started and reset in parallel but stopped and read out individually by a second (B)counter or gate that counts the number of echos. so the theory is, the (B)counter counts echos and stops (A)counter1 when on the first echo, (A)counter2 is stoped on echo pulse 2 and so on until there are no more counters. the MCU is then free to read the counters out and do some maths and present the data.

I would like to know the nitty and gritty of how the commercial units do the data acquisition are they doing it at these speeds? i don't think so from what i read on the net for shallower GPR a higher base frequency is used but its the reflection time that gets reduced by a massive amount that results in the crazy high clock speed that i have calculated, and they are probably much higher when they use a GPR on a shallow setting..

so my parts list would look something like this..
MCU
LCD screen 
Rf Transmitter 20-100Mhz
Rf Receiver 20-100Mhz
Storage
GPS ( so the data can be mapped against an existing map)
1.2Ghz clock and counter

looking at Element14.com i am not seeing a easy way for me to be generating 1.2Ghz clock for the counter. I have located

8bit  Counter MC100E137FNG @ $20au each. its rated to 2.2Ghz :)
10ghz oscilator @$66au ea will need a gate and buffer 
ITDB02 2.4E LCD with touch screen 
UNO32 Arduino clone80MIPS 

RF transmitter and receiver to be located. or constructed from discrete components (the old school way. .that is the hard way)

so the plan is to us the 1Ghz oscillator to clock the counter until an echo signal is received, stop the clock and display the number that results. maybe i could use one counter and stop it with a second counter like the above idea but without the multiple counters, this will require me to make multiple passes at the one spot  but with a sample time of 200ns i think this could be an option for a hand held device. with a 1Ghz clock each count on the timer will be 1ns to get the 200ns that equals 60 reflected meters i would need to count to 200. a count of 256 would be equal to 38.4 meters if our power level allows. 

that leads me to another method of capturing multiple echo's with one timer, some how it maybe possible to alter the power of the ping in say 5 steps then make a reading at each power level and accumulate the data into something understandable. 

having troubles of thinking of a place that would be good to test this. maybe a cemetery but thats just a bit rude.. I  know of a place where i could use it to find some interesting structures but i need to be able to confirm my GPR results, ie dig a hole.. thats why a cemetery would be good (for at least the first 6 or so feet of depth).. the plots are all marked out in rows nice and neat and uniform.

So over the next few weeks i might gather up some bits and pieces and see what can't be seen..

Friday 14 September 2012

I am lost.. and i have a compass...

I haven't made a post in a while, been rather busy with different projects, went to Portugal for work bit of a whirl wind trip.. but back to the electronics fun and games..

For one of my many side projects it needs a compass to know where it is. this device is to be aware of its location and environment to some degree. I need to know which way is up :)

I purchased from ebay a HMC5883L breakout board for about $15 delivered. once it arrived i located a library and some example code and it worked as advertised when i soldered it to a prototype shield and compiled the code and uploaded it to the mega2560. I thought sweet this will be great. i proceeded to load the code on my MAX32 chipkit arduino clone, i am planning to use this as my main dev platform as its a beast it rips through code at 80MIPs which is ideal for my application as i need the speed to update a graphical LCD at a nice rate a MEGA2560 doesn't have the grunt i need, i like the arduino IDE.

I loaded up the MAX32 with the example code and opened up the serial monitor to see whats doin.
things looked good, i was getting a similar output to the mega, then I did a full rotation of the compass and was not happy with the full results..

The mega gave me a nice 0-360' degree output as i rotated it about.
The MAX32 gave me 0-90' degrees then 0-90' (four times) and it had big holes where the output would jump from 45-75 with no steps between.
This is with the same code using the same compass wired to the same two pins.

I searched around on the net and found that there is a page that states the current status of various library's for the MAX32 and UNO32 platforms. this page didn't look like it had been updated in some time, i i took note of what they were saying. they report that the wire library produces bad stop bits when using the max32 hardware. it works with a uno32 (i tested it), so i then searched the net for any glimmer of hope that i could use the hardware i2c port on the mega, only to find no real info or help. that said i haven't hassled the manufacturer yet.

 Seeing as thou i couldn't find a answer to why the wire library wasn't working without reading all the header files and arduino dev bugs and stuff like that, i decided to bit bang me a IIc I2c I^c port on the max32.  now that i have completed this, i will dump the code at the end of this post. its a simple bit of code that is broken up in to the essential sections, i hope its not too confusing i have been modifying this for the last two weeks trying different things to explain my results, so there could be a bit of left over crap from previous methods i have tried..

So I seem to have replicated the hardware port 100% exactly the same in my bit banging code. I say this because i get exactly the same results as the example code produces.. that is, on the MEGA2560 i get nice results 0-360' degrees as i rotate the compass chip. with exactly the same code on the MAX32 i get the same results as the example code, 0-90' degrees four times with a hole in the results.. YAY i can copy something that doesn't work..

I have taken both boards to work and connected up the CRO probes to the mega and looked at a bit of the waveform that works.. then repeated the operation on the MAX32 and looked at the waveforms they looked ok until... what i  think is the result of a read command the voltage is a little lower than the rest of the transaction.. it was at 3.0v the chip and bus is referenced to the 3v rail when connected to both the mega and max32.. i was worried that the bus voltage might be a little low for the mega as its a 5v device and a Voh of 3.0v might not be read as a high on the mega. but testing has proven that the mega is happy with this for a Vih.



Code....


#define SDA_PIN  13  //20  //76
#define SCL_PIN  12  //21  //75
#define DRDY_PIN 74

#define HMC5883_W_add 0x1E
#define HMC5883_R_add 0x1E
#define HMC5883_A_add 0x1E      

#define CONFA 0x00
#define CONFB 0x01
#define MODER 0x02
#define OUTXH 0x03
#define OUTXL 0x04
#define OUTZH 0x05
#define OUTZL 0x06
#define OUTYH 0x07
#define OUTYL 0x08
#define STATU 0x09         // bit 1 of result 0 = data has been read
// bit 0 of result 1 = data is read to be read/
#define IDRA  0x0A
#define IDRB  0x0B
#define IDRC  0x0C
//  CONFIG_B value bits 765
#define scale088 0.73          //  000
#define scale130 0.92          //  001
#define scale190 1.22          //  010
#define scale250 1.52          //  011
#define scale400 2.27          //  100
#define scale470 2.56          //  101
#define scale560 3.03          //  110
#define scale810 4.35          //  111


//                   SShhhBB        // hhh = hz setting
#define CONFIG_A  0b01111000      // 
#define CONFIG_B  0b00000000      // 001 = 1.3Ga 000 = 0.88Ga
#define CONFIG_M  0b00000000      // continous read mode

float Scale_Factor = scale088;
int compassXYZ[6];
char temps[10];
char data;
char x;




void IIC_Init(void);          // sets up the hardware for idle state
void IIC_Startbit(void);         // sets the bus into start_bit cond.
void IIC_Stopbit(void);          // sets the bus into stop_bit cond.
unsigned char IIC_Send_Byte(unsigned char data);
void IIC_Send_Add_RW(unsigned char add,unsigned char rw);
unsigned char IIC_ReadByte(void);
char w;      // used to waste time.

float compass_read(int);
float raw_to_gs(int);

char count = 0;
char t,temp1,temp2,temp3;



//------------------------------------------------------------------------------
void setup(void)
{
  pinMode(SDA_PIN,OUTPUT);   // data
  pinMode(SCL_PIN,OUTPUT);   // clock
  digitalWrite(74,LOW);
  pinMode(DRDY_PIN,INPUT);   // DRDY_PIN data ready for reading INTor flag.

  Serial.begin(9600);
  Serial.println("Done");
  IIC_Init();  // sets up pins for I2c chat
  compass_init();
//  while(1);
}


void loop(void)
{
  if (digitalRead(DRDY_PIN) == 1)
  { 
    compass_read(compassXYZ);
    Serial.print(" X ");
    Serial.print(compassXYZ[0]);
    Serial.print(" Z ");
    Serial.print(compassXYZ[1]);
    Serial.print(" Y ");
    Serial.println (compassXYZ[2]);

    raw_to_gs(compassXYZ);
    Serial.print("          Heading -----> ");
    float head = atan2(compassXYZ[2],compassXYZ[0]);
    if (head < 0)
        head += 2 * PI;
   
    if (head > 2 * PI)
        head -= 2 * PI;
       
        head = head * 180/M_PI;
    Serial.println(head);
  }
  else
    Serial.print("*");

}


void compass_init(void)
{
  unsigned char IIC_t0 = 0;
  unsigned char IIC_t1 = 0;
  unsigned char IIC_t2 = 0;
  unsigned char IIC_t3 = 0;
  unsigned char IIC_t4 = 0;
  unsigned char IIC_t5 = 0;
  unsigned char IIC_temp0 = 0;
  unsigned char IIC_temp1 = 0;
  unsigned char IIC_temp2 = 0;
  unsigned char IIC_tempL=0;
  IIC_StartBit();
  IIC_Send_Add_RW(HMC5883_A_add,0);      // select the chip and command
  IIC_t0= IIC_SendByte(CONFA);      //  send address to write
  IIC_t1= IIC_SendByte(CONFIG_A);   // write value to register
  IIC_StopBit();
  delay(100);
  IIC_StartBit();
  IIC_Send_Add_RW(HMC5883_A_add,0);      // select the chip and command
  IIC_t0= IIC_SendByte(CONFB);      //  send address to write
  IIC_t3= IIC_SendByte(CONFIG_B);     // Write value to register
  IIC_StopBit();
  delay(100);
  IIC_StartBit();
  IIC_Send_Add_RW(HMC5883_A_add,0);      // select the chip and command
  IIC_t0= IIC_SendByte(MODER);      //  send address to write
  IIC_t5= IIC_SendByte(CONFIG_M);
  IIC_StopBit();
  delay(100);
  IIC_StartBit();
  IIC_Send_Add_RW(HMC5883_A_add,0);      // select the chip and command
  IIC_SendByte(CONFA);          // addressing CONFIG_A reg
  IIC_StopBit();

  IIC_StartBit();
  IIC_Send_Add_RW(HMC5883_A_add,1);      // select the chip and command
  IIC_temp0 = IIC_ReadByte();      // read CONFIG_A
  IIC_StopBit();

  IIC_StartBit();
  IIC_Send_Add_RW(HMC5883_A_add,0);      // select the chip and command
  IIC_SendByte(CONFB);          // addressing CONFIG_A reg
  IIC_StopBit();

  IIC_StartBit();
  IIC_Send_Add_RW(HMC5883_A_add,1);      // select the chip and command
  IIC_temp1 = IIC_ReadByte();      // read CONFIG_B (address auto increment)
  IIC_StopBit();

  IIC_StartBit();
  IIC_Send_Add_RW(HMC5883_A_add,0);      // select the chip and command
  IIC_SendByte(MODER);          // addressing CONFIG_A reg
  IIC_StopBit();

  IIC_StartBit();
  IIC_Send_Add_RW(HMC5883_A_add,1);      // select the chip and command
  IIC_temp2 = IIC_ReadByte();      // read MODE register
  IIC_StopBit();

//   Debug info

   Serial.println(IIC_t0,HEX);
   Serial.println(IIC_t1,HEX);
   Serial.println(IIC_t2,HEX);
   Serial.println(IIC_t3,HEX);
   Serial.println(IIC_t4,HEX);
   Serial.println(IIC_t5,HEX);
   Serial.print("CONFIG_A =");
   Serial.println(CONFIG_A,HEX);
   Serial.println(IIC_temp0,HEX);
   Serial.print("CONFIG_B =");
   Serial.println(CONFIG_B,HEX);
   Serial.println(IIC_temp1,HEX);
   Serial.print("CONFIG_M =");
   Serial.println(CONFIG_M,HEX);
   Serial.println(IIC_temp2,HEX);
  
}


int compass_read(int comp[3])
{
  //  this attempts to read 6 bytes out of the compass from 0x03 to 0x09
  //
  unsigned char XH=0,XL=0,ZH=0,ZL=0,YH=0,YL=0;
  //  unsigned char temp_data;

  IIC_StartBit();                    // send a start condition on the bus
  IIC_Send_Add_RW(HMC5883_R_add,0);  // send the address with Write mode
  IIC_SendByte(0x03);                // send the value of the address we want to read
  IIC_StopBit();

  IIC_StartBit();                    // send a start condition on the bus
  IIC_Send_Add_RW(HMC5883_R_add,1);  // send the address with Write mode  
  XH = IIC_ReadByte();          // X high read from chip
  IIC_StopBit();

  IIC_StartBit();                    // send a start condition on the bus
  IIC_Send_Add_RW(HMC5883_R_add,0);  // send the address with Write mode
  IIC_SendByte(0x04);                // send the value of the address we want to read
  IIC_StopBit();

  IIC_StartBit();                    // send a start condition on the bus
  IIC_Send_Add_RW(HMC5883_R_add,1);  // send the address with Write mode  
  XL = IIC_ReadByte();          // X Low  next byte
  IIC_StopBit();

  IIC_StartBit();                    // send a start condition on the bus
  IIC_Send_Add_RW(HMC5883_R_add,0);  // send the address with Write mode
  IIC_SendByte(0x05);                // send the value of the address we want to read
  IIC_StopBit();
 
  IIC_StartBit();                    // send a start condition on the bus
  IIC_Send_Add_RW(HMC5883_R_add,1);  // send the address with Write mode  
  ZH = IIC_ReadByte();          // Z high
  IIC_StopBit();

  IIC_StartBit();                    // send a start condition on the bus
  IIC_Send_Add_RW(HMC5883_R_add,0);  // send the address with Write mode
  IIC_SendByte(0x06);                // send the value of the address we want to read
  IIC_StopBit();

  IIC_StartBit();                    // send a start condition on the bus
  IIC_Send_Add_RW(HMC5883_R_add,1);  // send the address with Write mode  
  ZL = IIC_ReadByte();          // Z Low
  IIC_StopBit();

  IIC_StartBit();                    // send a start condition on the bus
  IIC_Send_Add_RW(HMC5883_R_add,0);  // send the address with Write mode
  IIC_SendByte(0x07);                // send the value of the address we want to read
  IIC_StopBit();

  IIC_StartBit();                    // send a start condition on the bus
  IIC_Send_Add_RW(HMC5883_R_add,1);  // send the address with Write mode  
  YH = IIC_ReadByte();          // Y high
  IIC_StopBit();

  IIC_StartBit();                    // send a start condition on the bus
  IIC_Send_Add_RW(HMC5883_R_add,0);  // send the address with Write mode
  IIC_SendByte(0x08);                // send the value of the address we want to read
  IIC_StopBit();

  IIC_StartBit();                    // send a start condition on the bus
  IIC_Send_Add_RW(HMC5883  _R_add,1);  // send the address with Write mode  
  YL = IIC_ReadByte();          // Y Low
  IIC_StopBit();          // we have read all the bytes we need and finish the conversation

  comp[0] = (XH << 8) + XL;
  comp[1] = (ZH << 8) + ZL;
  comp[2] = (YH << 8) + YL;

  return *comp;          // tell everyone what we heard

}


float raw_to_gs(int Scaled[3])
{
  float RESULTS[3];
  RESULTS[0] = float(Scaled[0]) * Scale_Factor;
  RESULTS[1] = float(Scaled[1]) * Scale_Factor;
  RESULTS[2] = float(Scaled[2]) * Scale_Factor;
  return *RESULTS;
}

// I2c IIC  I^c interface core below here

void IIC_Init(void)          // sets up intial pin state
{
  pinMode(SCL_PIN,OUTPUT); 
  pinMode(SDA_PIN,OUTPUT); 
  digitalWrite(SDA_PIN,HIGH);  // master idle mode   
  digitalWrite(SCL_PIN,HIGH);  // master idle mode   
}


void IIC_StartBit(void)      // sends a start condition on the IIC bus
{  // data changes while clock high
  pinMode(SDA_PIN,OUTPUT);   
  delayMicroseconds(21); 
  digitalWrite(SCL_PIN,HIGH);
  delayMicroseconds(21); 
  digitalWrite(SDA_PIN,LOW);
}

void IIC_StopBit(void)        // sends/creates a stop condition on the IIc bus
{       // data changes while clock high
  pinMode(SDA_PIN,OUTPUT);   
  digitalWrite(SCL_PIN,HIGH); 
  delayMicroseconds(21); 
  digitalWrite(SDA_PIN,HIGH);
}

unsigned char IIC_SendByte(unsigned char data)        // sends  byte bit by bit
{  // data changes while clock low
  //  char dla;
  //  data = 0xFF;
  unsigned char ack_result;
 
  pinMode(SDA_PIN,OUTPUT);
  delayMicroseconds(21);          
  // Start of bit 8 MSB 
  digitalWrite(SCL_PIN,LOW);     
  delayMicroseconds(21);             //waits a little bit of time to wait for clock to stablize
  if ((data & 0b10000000)==0)
    digitalWrite(SDA_PIN,LOW);
  else
    digitalWrite(SDA_PIN,HIGH);      // sets or clears the data line according to the bit 8
  delayMicroseconds(21);            // lets data settle on the bus
  digitalWrite(SCL_PIN,HIGH);      // tells slave to read the pin
  delayMicroseconds(21);            // gives the slave time to read the pin
 // FINSIH of bit 7 START of bit 6  // and repeats for the rest of the byte
  digitalWrite(SCL_PIN,LOW);   
  if ((data & 0b01000000)==0)
    digitalWrite(SDA_PIN,LOW);
  else
    digitalWrite(SDA_PIN,HIGH);
  delayMicroseconds(21);
  digitalWrite(SCL_PIN,HIGH);
  delayMicroseconds(21);
 // FINSIH of bit 6 START of bit 5
  digitalWrite(SCL_PIN,LOW);
  if ((data & 0b00100000)==0)
    digitalWrite(SDA_PIN,LOW);
  else
    digitalWrite(SDA_PIN,HIGH);
  delayMicroseconds(21);
  digitalWrite(SCL_PIN,HIGH);
  delayMicroseconds(21);
 // FINSIH of bit 5 START of bit 4
  digitalWrite(SCL_PIN,LOW);
  if ((data & 0b00010000)==0)
    digitalWrite(SDA_PIN,LOW);
  else   digitalWrite(SDA_PIN,HIGH);
  delayMicroseconds(21);
  digitalWrite(SCL_PIN,HIGH);
  delayMicroseconds(21);
 // FINSIH of bit 4 START of bit 3
  digitalWrite(SCL_PIN,LOW);
  if ((data & 0b00001000)==0)
    digitalWrite(SDA_PIN,LOW);
  else
    digitalWrite(SDA_PIN,HIGH);
  delayMicroseconds(21);
  digitalWrite(SCL_PIN,HIGH);
  delayMicroseconds(21);
 // FINSIH of bit 3 START of bit 2
  digitalWrite(SCL_PIN,LOW);
  if ((data & 0b00000100)==0)
    digitalWrite(SDA_PIN,LOW);
  else
    digitalWrite(SDA_PIN,HIGH);
  delayMicroseconds(21);
  digitalWrite(SCL_PIN,HIGH);
  delayMicroseconds(21);
 // FINSIH of bit 2 START of bit 1
  digitalWrite(SCL_PIN,LOW);
  if ((data & 0b00000010)==0)
    digitalWrite(SDA_PIN,LOW);
  else
    digitalWrite(SDA_PIN,HIGH);
  delayMicroseconds(21);
  digitalWrite(SCL_PIN,HIGH);
  delayMicroseconds(21);
 // FINSIH of bit 1 START of bit 0
  digitalWrite(SCL_PIN,LOW);
  if ((data & 0b00000001)==0)
    digitalWrite(SDA_PIN,LOW);
  else
    digitalWrite(SDA_PIN,HIGH);
  delayMicroseconds(21);
  digitalWrite(SCL_PIN,HIGH); 
  delayMicroseconds(21);
  // FINSIH of bit 0 START of ACK bit
  digitalWrite(SCL_PIN,LOW);  
  pinMode(SDA_PIN,INPUT);        // set data pin to read
  delayMicroseconds(25);
  digitalWrite(SCL_PIN,HIGH);    // clock in the ack signal
  delayMicroseconds(25);
  ack_result = digitalRead(SDA_PIN);   
  digitalWrite(SCL_PIN,LOW);   
  digitalWrite(SDA_PIN,LOW);     // could allow clock streatching here wait for ack (if high wait for low)    
  pinMode(SDA_PIN,OUTPUT);        // set data pin to write
  delayMicroseconds(21);
//added above two lines since scoped. seems to work.
  return ack_result;
}

unsigned char IIC_ReadByte(void)        // receives a byte bit by bit.   
{
  unsigned char b,result = 0,var;   // index bit
//  digitalWrite(SDA_PIN,LOW);
  pinMode(SDA_PIN,INPUT);      // done after clock is low to avoid stop/start cond

  digitalWrite(SCL_PIN,LOW);   // makes sure the bus is low
  delayMicroseconds(21);
  digitalWrite(SCL_PIN,HIGH);  // pull clock high
  delayMicroseconds(21);        // wait for data to be valid
  var = digitalRead(SDA_PIN);  // read the pin
  if (var==1)                 
    result = (result | 0b10000000);    // load up the result
  digitalWrite(SCL_PIN,LOW);   // could move up three line to above the if and use the if time for delay
  delayMicroseconds(21);

  digitalWrite(SCL_PIN,HIGH);    // set the clock
  delayMicroseconds(21);
  var = digitalRead(SDA_PIN);    // read the data pin
  if (var==1)
    result = (result | 0b01000000);  // store result
  digitalWrite(SCL_PIN,LOW); 
  delayMicroseconds(21);          // start next bit

  digitalWrite(SCL_PIN,HIGH);
  delayMicroseconds(21);
  var = digitalRead(SDA_PIN);
  if (var==1)
    result = (result | 0b00100000);
  digitalWrite(SCL_PIN,LOW); 
  delayMicroseconds(21);

  digitalWrite(SCL_PIN,HIGH);
  delayMicroseconds(21);
  var = digitalRead(SDA_PIN);
  if (var==1)
    result = (result | 0b00010000);
  digitalWrite(SCL_PIN,LOW); 
  delayMicroseconds(21);

  digitalWrite(SCL_PIN,HIGH);
  delayMicroseconds(21);
  var = digitalRead(SDA_PIN);
  if (var==1)
    result = (result | 0b00001000);
  digitalWrite(SCL_PIN,LOW); 
  delayMicroseconds(21);

  digitalWrite(SCL_PIN,HIGH);
  delayMicroseconds(21);
  var = digitalRead(SDA_PIN);
  if (var==1)
    result = (result | 0b00000100);
  digitalWrite(SCL_PIN,LOW); 
  delayMicroseconds(21);

  digitalWrite(SCL_PIN,HIGH);
  delayMicroseconds(21);
  var = digitalRead(SDA_PIN);
  if (var==1)
    result = (result | 0b00000010);
  digitalWrite(SCL_PIN,LOW); 

  delayMicroseconds(21);
  digitalWrite(SCL_PIN,HIGH);
  delayMicroseconds(21);
  var = digitalRead(SDA_PIN);
  if (var==1)
    result = (result | 0b00000001);
  digitalWrite(SCL_PIN,LOW); 
  delayMicroseconds(21);
 
  pinMode(SDA_PIN,INPUT);
  delayMicroseconds(21);       
  digitalWrite(SCL_PIN,HIGH);   
  delayMicroseconds(25);       
  var = digitalRead(SDA_PIN);
  digitalWrite(SCL_PIN,LOW);
  pinMode(SDA_PIN,OUTPUT);
  delayMicroseconds(21);       
//  digitalWrite(SDA_PIN,HIGH);
//  result = 0;
  return result;
}


void IIC_Send_Add_RW(unsigned char IIC_add,unsigned char IIC_rw)
{
  unsigned char IIC_data = 0;
//  Serial.print("in add :");
//  Serial.print(add,HEX);
 IIC_data = (IIC_add <<1);      // shifts address to MSB's
  IIC_data = (IIC_data | IIC_rw);    // adds rw bit in LSB 0=write 1 = read as per datasheet.
//  Serial.print(" out data :");
//  Serial.println(data,HEX);
  IIC_SendByte(IIC_data);

}







What the above code attempts to do is..


setup
prep the SDA, SCL pins for I2c operation

Init_Compass
init the compass chip.
         this sends CONFIG_A,B,M to register 0,1,2 it then reads these registers and might print them on the serial port for debugging.



Loop
this reads registers 3-8 of the compass and does a little maths on it and produces the heading value depending on how the compass chip is rotated.

raw_to_gs
    scales the results of the compass_read values

the main loop then does the maths on the result to get the heading.

This code (for me) gives the same results as the HMC5883 example code i found.

If anyone can point out where i have gone wrong please publicly ridicule me in the comments section, just be sure to show where i went wrong..

i am sure someone will tell me that my problems are speed related, but i get the same results at 10khz as 370khz.. as measured on the CRO at work. i have tired slowing things down and speeding up but all gives the same results.. pull up resistors are 2k2.. i cant explain the small sections of 3.0v on the bus when using the MAX32..

Wednesday 30 May 2012

Batteries. and a kick Arse PSU

I got an Email the other day about the auction of all the left over parts from the submarine project. today was the day, i took a day off work, as i had spied a very very nice TDK-Lambda Gen 1500Watt PSU on the website i thought i would like that. looking thru the rest of the offerings i took note of a list of lots that i was interested. $600 later i was a happy lad. I didn't win the bid for the PSU but had worked with the guy that did win the bid on three of them, I inquired if he wanted all three, he said i may buy one from him for what it cost him, works out to just under $500au.. SCORE!!!! i also came home with boxes of random parts most purchased at $10 a lot. the best score out of the random parts was the Li-ion batteries that i found. there is
32x 11ah cells
5x     5ah cells
4x  6.3ah cells
5x   17ah cells
20x   2ah cells

I also scored a Few reels of Mosfets and opto-Isolators not 100% sure on the quantity or specs just yet it was a lucky dip box :)

not too sure what i will do with them all but i will find something :) I guess i should probably start thinking of how to charge these guys up and use them, that alone will be a fun exercise, wonder if i can get them to charge in parallel and discharge in series, will probably take a lot of mosfets but i might be lucky the ones on the reels may do the job. i doubt i would be really lucky and find both P and N channel mosfets, there is a slim chance these mosfets are from the thruster controllers which used both N channel and P channel mosfets that can handle lots of power... time for me to take over the world approaches...



ARGH!!!! OS X update does me in.

Being a Mac user A pop up message told me i had updates to install. I thought i had better hit this it might make my virtual machine run better (it suffered in performance when i updated last time, maybe just a coincidence i dunno), but no it in actual fact broke MPLAB_X a net beans ide i use to program PIC MCU's.

I have so far tried every link suggesting anything that might help but no, I Wiped my hard drive re-installed a fresh copy of OSX Snow leopard then restored my virtual machine and installed a fresh copy of virtual box and MPLAB X. tested out how solid works runs, At this point i was happy i could rotate a model and not sit there and wait while it thinks about rotating it and showing me the result it was running smooth. so i then tried to program a PIC MCU for one of my many projects i have on the go, Only to discover that MPLAB could no longer contact my pickit3 so i went and grabbed my ICD3 and the same thing, when you try to access the programmer the IDE says that the previously selected programmer is no longer available, and to select one from the list. only problem is that the list is empty.

I loaded up the VM to test my hardware and it all checked out, so i thought maybe the new version of MPLAB X 1.10 was at fault so i downgraded this to v1.0 all to no avail, i loaded up v1.1 in windows VM and i could access both the programmers, i found a little utility that switches the drivers/firmware in the ICD3 to MPLAB X but that didn't help either, starting to get really pissed at this..

As i said above i have tried a fresh install of OSX and tested the functionality of the programmers at each step of the update process but they have never worked natively on OSX since they stopped working, but the thing i don't understand is how MPLAB X under OSX can't see the programmers but MPLAB X under a windows VM machine on the same OSX machine can use them.. this is very annoying..

recap :-
mac laptop 32bit OSX Snow Leopard
windows VM using MPLAB 8.73a and MPLAB X can access both the ICD3 and the Pickit3
OSX MPLAB X Cannot access either the ICD3 or the Pickit3.
i have accessed both programmers and updated the firmware to the latest but still no dice..


ARGH!!!!!!!! any suggestions?

Saturday 19 May 2012

plastic in all the wrong places...

so i had a problem with plastic building up over the top of the nozzles, i think i have found a rather convoluted solution :)

I have a 4mm ID brass tube that i have stuffed a PTFE liner into that was 4.05mm OD and 3.2mm ID.
this is then pressed into the top of the nozzle, this was drilled out to 4.72mm the brass tube has a OD of 4.85mm so its supposed to be a tight fit. (this theory is great, execution was not so great the hole ended up too big and i had to cross drill and pin the brass to the nozzle the first one. this was done to so the hole only just hit the brass tube and did not Perice the ptfe liner (no i am not that good,i was lucky very lucky) .

 This brass tube that sticks up 20mm up from the nozzle was still getting hot enough to soften the ABS, and the problem is now 20mm higher, as i have a Aluminium carriage plate i thought that would make a bloody great heatsink, i already had a fan on it to keep the stepper motor cool, so the plate would be well below 105'c (the point where ABS gets soft). I made up a little brass lump that i pressed into the aluminium plate that has a hole to suit the brass tube, this now keeps the top of the nozzle at about 50'c when no fan is on and the unit has been soaking for an hour or so. with a fan i think this will be a viable solution.

Its 15mins since i typed the above line and it seems that a 0.25mm nozzle is just too small for my extruder.. I have come to this conclusion by drilling out the 0.25mm nozzle to 0.4mm and the plastic is flowing nicely again. i cleaned the nozzle before i drilled it but it didn't help. but a bigger hole fixed my stripping issue, i maybe able to re-visit the idea of 0.25mm bolt once i get all the other problems sorted out... I will be bench testing this setup for a while before i go and bolt it all back up and attempt a print, i wonder if slic3r supports 3 materials with 3 different nozzle sizes?

Saturday 12 May 2012

Video of the Vavle nozzle bench test.

Last night and yesterday i was rather industrious and made some good headway with my extruder, i tore it down after using it for a little bit for some preliminary testing, i would get close but then decide to add or change something so i would have to start again. This morning i have done a first test on the first nozzle, it also the first time i have tested a 0.25mm nozzle, there is nothing like changing only 1 thing at a time :D.


in this video you can see the valve work as the filament is pushed by the extruder the nozzle moves down and the valve slides out of the way ready for printing, there is one little problem with this profile of nozzle the step in the tip has two problem, A) the valve gets caught on the edge, this can be solved by forming the edge of the valve more, this may require a thicker but narrower valve. And B) the valve (if watch carefully) is pushing the nozzle back up into the extruder, this may or may not be a problem. Either way i am very happy with the way this works for a first try this is Awesome..

each time you hear the stepper feed its going slowly at a rate of 100mm/min and feeding 5mm of stock each time, tests will prove how well this actually works out, these valves are very crude, if i had better tools i would have made them 8mm wide and possibly attempted to put a V grove in the end to see if that helps with the riding up on the nozzle, i can see this riding action causing a problem down the path when the nozzle becomes worn from repeated opening and closing, but for a first attempt i am happier than a pig in mud..

My Powered Dividig Head

I  need a powered Dividing head for the Mill so i can make gears and drive bolts for the printer, i found  something close on ebay.. and i have since made up an frame for it to attach a stepper motor to the chuck..
 here is the chuck there is a locking screw that holds the back to tighten the jaws and while milling.
 Have i mentioned i am a lazy bastard.. I want to make gears with nice fine teeth and drive bolts for my printer with out breaking a sweat, done that too much already.. so i have devised a way to attach a stepper motor to the back of it and still maintain the ability to mount it either vertically or horizontally.  

I took a 12mm 1.25mm pitch bolt and drilled a hole in the end to match the steppers shaft, then i made a flanged shaft to attach the back of the chuck, on this i have a hobbed section that the bolt will run in, as it does the chuck will turn, but alas my measurements we off by 0.5-1mm and the drive bolt does not make proper contact with the flanged shaft. so i am going to have to print (slowly) a new worm and spur gear that i can use in this frame to mill a metal one out that will be able to turn while milling. the plastic one will require me to lock off the chuck when i make a cutting pass, i should be able to make the spur gear i need and the worm on the lathe. so many projects on the go it will be good to get some finished...

Update 10.. Valves are so rich and warm :)

My last post was a mess was downloading all the photos from my iphone so i jammed pics in later and they only sorta suit the words.. Meh...


I had to take apart my Extruder as i had a problem with the plastic building up above the nozzle and coming out the sides (must have been a lot of force up top there). to fix this i added tube to the top of the nozzles, these poke up through the carriage plate. while i had it in bits i thought why not see about my valves? see if they can work, i was going to just try them out separately while i was printing but the blobs up top forced my hand, thanks to my mate at work Dave, i got my paws onto some spring steel that was 10mm wide and i dunno how thin 0.5 at a guess, and bent them in to a Z shape that hugged the ends of my heater blocks..


 here you can see the valve made from spring steel bent. you can also see the brass tube on the top of the nozzle on the up turned carriage. it slides up inside the peek and goes thru the plate.
 see it fits :)
 here i have installed all three heater blocks, with resistors, these are held in place by a split brass tube. the nozzles are free to move up and down about 5mm, as they do they push the spring steel down and the taper on the nozzles push it to the side.
as the tips push the valves to the side the valves ride and spring up above the height of the print layer.and don't clip the print job.


here you can just see the tips of the nozzle poking down past the vlaves just enough to clear the print job.

these Nozzles will have to be leveled, i plan to do this by slapping down some emery paper or wet and dry sand paper on the bed and gcode it to go back and forth and hope they all end up at the same level. you can see that each of the nozzles have a different profile to their tips this was a bit of machinist error and when i saw it i thought hey i can claim its a test, wanted to see the best shape to get the valves out of the way, i need to model (somehow) how they move so i can get it perfect.

Between you, me and the lamppost my third channel may not work too well, i have something out of alignment and this can only be fixed by a complete rebuild, one of my mates who has helped with the build is now really excited about the printer, before he wasnt totally commited now he has volunteered to build the next prototype, once i have finished poking at this one. so far i need to shrink the camshaft motor (nema17 is beyond "Steven Segal styles" overkill), from playing with this unit the camshaft rolls so nice (even without rolled edges) in the bearings i can use a PM-20 stepper and some gears. i have these sitting here from old ticket printers. i might need to increase the spring tension or the the ratio of the tension arms so i get more grip on the plastic and try out a hyena style drive bolt but i need my CNC mill and the dividing head to be finished for that.. if my brass tube upgrade works i will be set :) then i have firmware and gcode scripts to sort out.. time to buff up on my python.
 



Update 9.Victory is near....

Having received my new Arduino Mega and installed it i started to play around with my printer..

I got impatient waiting to finish the mill so i thought i would see what i can do about the grip issue.. i cleaned the hobbing on the bolt and gave it a whirl, and what do you know, i could feed filament at 140mm/min into the hotend, then the motor would stall..
Talking to the peeps on #reprap i decided to ignore what they were saying and install a stronger motor.
$30 later including postage i was waiting for a new 62oz stepper motor...  this arrived very promptly.. Ausxmods.com.au i cut the wires nice and short and installed  a header onto the motor and a socket on the loom, it was a pain to re-wire the whole carriage to replace a motor..




So i have been printing quite nicely YAY.. i still have a lot of little settings that i need to tweak with slic3r or Skeinforge to get some nice printouts but i keep adding things so i never actually get to a happy point where i can claim complete victory..  See the "Things I have printed" page for the results..

To stop the extruded plastic from curling up and deforming i have a heated bed this was not enough, i had to also add a fan, i made one fan shroud that was ugly but encouraging, so i made a new one and this one is sweet the holes where the air come out have been reduced to only where i want them, but opened up more so i get better air flow, as sweet as this one is i think i need a second fan on it, i do have a problem i have a the fan driven off the arduino mega's pin 11 according to the screen printing on the board, the documentation and numerous websites pin 11 is PWM capable, i have exactly the same mosfet driver circuit as my hot ends, which are optically isolated and driven from a separate 12V PSU, with the hot end resistors are 4r7 so if i drive them all at 100% at 12v i will take 7.5amps, currently i am only experimenting with one hot end, but will have to keep that in mind later, until then i have no idea how to get his fan to PWM, wont spin until i give it a S value of 255. so i cant slow it down.



ok so it not perfect but it does the job, have a plan to print a nicer one, cuz its so big i need to add some LEDS to it, i bought some from jaycar and paid to much for them if you ask me.
i found that my extruder being all Alu needs a fan to keep it cool so i just hotglued one on top to blow air on the frame. the intake for the air that gets blown on to the print job is drawn too close to the bed and is to warm i think. the middle shot is of the old shroud the new one covers the bearings, they both blow air past the smooth rods so i will have to make some socks up to cover them to keep dust out of my bearings while i am at it i will make some socks for the other smooth rods too.. velcro should do the job.

The new stepper on the extruder makes a big difference i could only retract the filament @2mm/s before the motor would stall.. and i noticed a strange thing, when i have 0.25mm of retract with the new stepper i get nice prints if i turn the retract up any farther it gets worse.. but i dont care about that for now i have other problems with the extruder..

my plastic was melting above the nozzle inside the peek block this area/void was to be where the nozzle was able to lift up so it was out of the way and the valve can close.. I made a mission to Kellets hobbies (they are nice guys as long as you dont get there right on closing) to see if they
 have some ptfe tubing, forgetting that i have some on the Mill as air lines for the piston, and i bought some brass tubes that range in diameters all around 3mm. some metric some imperial. got that home and pulled apart my printer, took the  extruder off the carriage and removed the hot end, had to first heat the hot end up to break the blob of plastic off, then use a hammer and knock out the plug of plastic that built up above the nozzle. i then cleaned out the nozzle the best i could and drilled 5mm into the top with a 3.5mm drill, cut a piece of brass tube that has a OD of 3.55mm and a ID of 3.05mm and hammered the tube into the top of the nozzle see the pics.


this should stop the plastic from building up in the area above the nozzle and allow the filament more grip on the brass to lift the nozzle up so the valves can close.. if i move the fan to the front of the extruder the thin tube will poke up above the aluminium plate that my carriage is made out of, and will get cooled a little and stop it melting too high up.. (i hope)



 here is the first decent print i have done. this was/is vodka tight. i thas a seam line up the back you can see in the pic, i have since been trying to get rid of that, came close but ended up changing stuff and have to re-tune the settings..