Now that we live in he age of the Internet-of-Things (IOT), I find that these ‘things’ have to communicate to a normal web server at some point.

The problem of course is how best to send data to the server and make sure what was sent is what was received. My preferred method is to use ‘Method GET’ which means that the data is encoded in the URL. It is easy to implement on just about any platform from Arduino UNOs to Arm Cortex processors. Every platform that supports 802.11 or 802.3 will have an example of using ‘Method GET’ to fetch a URL. Which means that the opportunity to send data is as easy as getting a URL.

The next problem is how to send binary data. Since the URL schema has special characters like, ‘”/?& that have meaning you cant just send binary data in the url. To be completely safe in a 7bit ASCII world, one needs to encode that data into some format.

For example if you wanted to send a number of 0x31EAA5 via a URL you could do http://127.0.0.1/?q=3271333 easily enough. That would be converting the number to a integer represented by ASCII characters. This method becomes cumbersome when there are multiple values to send: ?q1=555&q2=444&q3=333&q2=222

My preferred method of late is to send the data as a byte stream. Doing this requires some sort of ASCII armor, such as BASE64 or UUENCODING. Originally I started using base64 which creates GET URLs like: ?q=SSBhbSBEQVRBCg== which decoded on the receiving server would be ‘I am DATA’. But for whatever reason the encoding uses special characters for some data. Namely / and + characters. So a few variants of base64 have sprung up to change these characters to more friendly to URL or other standards.

Not wanting to deal with the hassles of base64. I decided to give base 16 a try as the encoding. This has worked out rather well. Base16 encoding is easy to implement in any language. And many have built in encoders/decoders.

So in the above example of the data being ‘I am DATA’ it would render as

?q=4920616D2044415441

It uses exactly twice as many bytes as the original data, but is perfectly safe to transport binary data. So the sacrifice is size vs safety and ease of implementation. I will almost always chose ease of implementation over any other factor.

On to the code:
Full Examples

Arduino code snippet

char base16[16]={ '0','1','2','3','4', '5','6','7','8', '9','A','B','C', 'D','E','F' };
// this expects byte theData[len] and byte theEncodedData[len*2]
void base16encode()
{
  char b1,b2; // bytes 1 and 2 of the encoded data
  byte ev; // the value to encode
  for (int lop=0; lop<theDataLength; lop++)
  {
    ev=theData[lop]; 
    b1=base16[( (ev>>4) & 0x0F)];
    b2=base16[( (ev) & 0x0F)];
    theEncodedData[(lop*2)]=b1;
    theEncodedData[(lop*2)+1]=b2;
  }
}

PHP snippet

function base16decode($data)
{
  $retv="";
  $base16str="0123456789ABCDEF";
  for ($lop=0; $lop<strlen($data); $lop+=2)
  {
    $oneByte=$data[$lop];
    $twoByte=$data[$lop+1];
    $v1=strpos($base16str,$oneByte);
    $v2=strpos($base16str,$twoByte);
    $theValue=($v1*16)+$v2;
    $av=chr($theValue);
    //echo "ob[$oneByte]tb[$twoByte] v1[$v1]v2[$v2] tv[$theValue] av[$av]| \n";
    $retv.=$av;
  }
  return $retv;
}

These code examples are written with the goal of being easy to read and understand rather than being examples of a good coding style.

Over the last few days I have been Tweeting photos with location but I am unhappy with how the maps are displayed.  So I made a bookmarklet to extract the map links.

Grab the GPSCoords bookmarklet by following the link then dragging and dropping it from there.

This is the first project that I am putting up using the Teensy 2.0 from PJRC

I am quickly becoming a super fan of the Teensy.  What used to take me days of coding and many hours of reading I can now do in minutes thanks to the work that PJRC has done with Teensydunio.

This is only the first of many projects that I will share based on the Teensy.

USB MIDI Servo Control In 23 Lines Of Code

I just put up my first alpha version of BasicToGCode.
basictogcode allows scripting of of RS274D g-code directly into EMC2 using BASIC (Beginner’s All-Purpose Symbolic Instruction Code).

It allows you to draw geometric shapes programmatically.

Today I wanted to see all the URLs I had visited in Firefox. I tell it keep my history for a very long time. I grow tired of bookmarking and managing those bookmars. I want to be able to do something like say: “What was that site I visited a few days ago that sold Widget X”.

Firefox3 stores its history in a file called places.sqlite which is in sqlite3 format. So with sqlite3 installed this is the command I used to export my history to a text file.

echo "SELECT datetime(moz_historyvisits.visit_date/1000000,'unixepoch'), moz_places.url,moz_places.title,moz_places.visit_count FROM moz_places, moz_historyvisits WHERE moz_places.id = moz_historyvisits.place_id ORDER by moz_historyvisits.visit_date; " | sqlite3 ./places.sqlite

Now I can add a grep to the end of that and find what I was looking for.

Why not just use the built in search for finding stuff? Well the simple reason is that I can add more complex searches easily using regex.

Plus I wanted to be able to export and save my history to a file where I can search it later. Without having to install some firefox extension.

If you wanted to get really adventurous you could do some php like this:


<table>
<?
$todo=”SELECT datetime(moz_historyvisits.visit_date/1000000,’unixepoch’), moz_places.url,moz_places.title,moz_places.visit_count FROM moz_places, moz_historyvisits WHERE moz_places.id = moz_historyvisits.place_id ORDER by moz_historyvisits.visit_date;”;
$dbh = new PDO(‘sqlite:places.sqlite’);
foreach ($dbh->query($todo) as $row)
{
//print_r($row);
echo “<tr>\n”;
echo “<td>”.$row[0].”</td>\n”;
echo “<td><a href=\””.$row[‘url’].”\”>”.$row[‘title’].”</a></td>\n”;
echo “</tr>\n”;
}
?>
</table>

This is an update to the Das Blinken Board from N&V June 2009. Der MagnetFelder uses a hall effect sensor to determine the relative strength and polar orientation of magnets.

Get the whole story in Nuts & Volts November 2009 and check out the website www.dasblinkenboard.com for the code.

I have been running into a problem when I am moving at really high IPM (inches per minute) using EMC2 Axis.

This image sums up the problem I was having:

Axis EMC2 was rounding my corners. I wanted it to go to that spot and then move on to the next line of G-Code. My friend Paul and I did a little research. He remembered that there was something on the emc2 list about CV problems. Where emc2 would try to keep a constant velocity.

As we researched we found out that emc2 implements “Trajectory Control” using the G61 and G64 commands.

So to solve the “problem” I was having. I told my Gcode file to use G61 Exact Path Mode. It got rid of the rounded corners I did not want.

Tonight I made two really cool things.

First up is the JavaScript G-Code Translate, Scale, Rotate tool.

http://www.unfocusedbrain.com/projects/2009/js-g-code/translate.html

I made this because sometimes I may get G-code from another generator or another person that I want to scale. This utility will scale all coordinates by a given value. X,Y,Z can be scaled independently.

It also can translate coordinates. Say you have a file that is 6″x6″ on the  XY plane starts at 0,0 and ends at 6,6. But you like to have objects centered at 0,0. No problem just paste the g-code tell it you want to translate X by -3 and Y by -3. Now the object will be centered at 0,0.

The second thing I wrote tonight was a Spoil Board Surfacing g-code Generator. I had written this before in php. So tonight I ported it to JavaScript and added input boxes to make generating spoil board code super easy.

http://www.unfocusedbrain.com/projects/2009/js-g-code/surface.html

I have started writing a little collection of functions in JavaScript that will generate g-code for me.

The idea is that I wanted an easy way to script gcode. For example if I want to drill a circle centered at X=0,Y=0,Z=0 and a radius of 1″, I wanted to be able to write drawCircle(x,y,z,radius); instead of the very unwieldy g-code:
(circle x=0 y=0 z=0 radius=1)
G0 X-1.000000 Y0.000000 (rapid to start)
G1 Z0.000000
G17 G2 X-1.000000 Y0.000000 I1.000000 J0.000000 Z0.000000
G0 Z0.500000 (safe z)
(end of circle)

Source code:

http://www.unfocusedbrain.com/projects/2009/js-g-code/jstogcode.html

This version supports: Lines, Boxes, Circles, Arcs, and deep circles.

Using an Atmega8 2x ULN2803’s and a “Magic Screen” device I made a CNC 2 axis machine.

CNC Magic Screen Machine Project Page

A few weeks ago I started this project knowing almost nothing about CNC, steppers, or controlling them w/ a microcontroller. I have learned so much in that short time and have a lot more to learn.

I chose to do a version of etch-cnc because it looked really simple. In that version it was an open-loop controller and just used 2 uln2803‘s to control 2 steppers. These steppers were driven by the parallel port on a pc using Axis in EMC2.

Steppers are super easy to control. The unipolar ones that a friend gave me have 4 coils. You give them voltage on 1 coil and it snaps to that coil. Give power to the next one and it moves clockwise or counterclockwise depending on the order. This is called a stepping sequence. If you know the stepping sequence for a motor, good. If not it is easy to figure it out.

Next is trying to get a computer to talk to a stepper. Since the steppers I was using were rated at 24V and can draw a considerable amount of current, I learned that you need a driver chip to help handle the current. That is where the uln2803 comes in. It has 8 channels of a “darlington array.” Each channel on the chip can handle 500ma. Following the example from etch-cnc I combined 2 channels for each step.

My first experiment was hooking up a ATMega8 and just having it send step pulses. It worked with only a handful lines of code. Now the fun part. Hook it up to a machine running EMC2 software w/ the parallel port driver. It turned out not so fun. Based on what I saw on the etch-cnc page it looked like you could have EMC2 send the step pulses over the port using pins 2-10. That is not how it works.

It works by using the parallel port to send step and direction. Example X axis uses pin 2 to indicate step and pin 3 to indicate direction. So every time the computer wants the stepper to step it puts a short pulse on pin 2 and sets the pin3 high or low depending on the direction it wants it to go. Easy enough to solve. I put the ATMega8 back in the loop. Connected 4 ports to the motor. Connected pin 2 to one of the interrupt pins and pin 3 to one of the portD pins. Then wrote a little ‘C’ code that setup the interrupts and told it that each time a rising edge interrupt happens to read the status of direction and do a step in that direction. The steps are done round-robin style.

Great, now after running the EMC2 config generator I could actually get it to step forward and backward w/ the software. Now I just added the code and wiring to do one more stepper for Y axis.

Then I did a config for a 2 axis machine. Well that didn’t work. Most of the g-code files included as samples expected a 3 axis mill. So I just told it that it was a 3 axis mill. I just ignore the stuff for the 3rd axis.

Now I started Axis (the program that outputs g-code to the parallel port in EMC2) and hit run. When axis starts it loads a little default file of g-code. It did not work as I expected. Then I noticed a comment in that default file that said that that file was not good for milling. So I loaded the spiral sample g-code and hit run. Worked perfectly. Almost.

I had to figure out the lead screw ratios and maximum step rates and such to make what was on the screen come out to the machine. Through a little trial and error I got it pretty close and the settings I used are on the Project Page.

I presented what I had to The Robot Group.

Next I started the cleanup to make the project presentable. I re-did the breadboard onto a soldier type board. I used the “ATMEGA8 Development Kit” by ProtoStack. This is the first time I used a pre-prepared board for an ATMega8 project. This board made it unbelievably simple for me to wire the project up and make it permanent. The board has many features that helped make it go faster. The first of which is that the ATMega8 has some pins scattered around and not in sequence. This board brings them all out away from the chip and puts them in order ie. PC0…PC7 all in one little row.

In the past I had always transferred my projects to perf-board w/ plated holes using bus wire to make all the connections on the back. It is difficult because the ATMega8 needs 2 sets of power to the chip… and for some reason they are reversed on either side of the chip. It is frustrating. But by using the ATMega8 Development kit I didn’t have to worry about any of that. The board has 2 really nice power planes and all the reversing directions have been taken care of for me. A few other features of the board that were helpful to the project were: Large prototyping area. Since I am using 2 unl2803 chips I needed the room. Built in reset button. I have a POST in the software and just hitting a button to run it is nicer than plugging and unplugging. Built in ISP programming header so I can change the chips brain.

Since I wanted to learn about CNC from the is project, part of the equation is Going from idea to output. The whole CAD/CAM thing. For the demo I did at the robot group I wanted to take the group logo and put it on the magic screen. I loaded the logo as a bitmap into Inkscape and traced it by hand keeping in mind that the CNC MSM cannot lift the pen. So I had to trace it in one continuous path. I exported it to dxf using “Better DXF” plugin for inkscape. Then converted the dxf to g-code using “Über DXF2GCODE.”

The last thing I did for the project was take the whole prototype to a friend who is really good at making cases more elegant. He trimmed it down, painted it, and reduced some of the wooden parts to get the final version of the setup.

The CNC Magic Screen Machine Project Page has a video and some shots of the prototype.
Also see more description of the building of the machine.

Thanks again to all the people who helped me w/ this project, Nyssa, Paul, Vern, Bob, and Rick.

« Previous PageNext Page »