Friday, October 10, 2014

May your antiquated book publishing models die, die, die!

Read an interesting review of what appears to be an interesting book, Hieroglyph.

I read the sample chapter and was ready to buy it. Book was "released" 14 Sep 2014. Clicked on the ebook button so I could read it straight away. "This publication is not available in your area" (Australia). Huh?

Oh well, maybe Amazon.com could help. Nope: "we do not have pricing for the Kindle version yet". Paperback? "Not available till 2015".

So here is a book publisher which will not sell me a book I would like to buy right now.

I can guess why of course. They want to sell hardcover versions for a few months, then paperback versions, then ebooks but only in USA. Then sometime in the middle of next year they'll get around to making ebook version available to Oz.

So of course I will wait till it's available as a Torrent, download it and pay nothing. Or simply forget about it. There are some people who like to buy hard copies of books. I'm not one of them. I don't have the room any more. I only buy electronic versions. (Yes, I do buy (some) ebooks, usually on the spur of the moment of course.)

And the final irony is that the book is about optimistic techno futures. Hah! hah!

Rigidbot arrived!

Last week my almost despaired of Rigidbot 3D printer kit arrived. Project was successfully funded in May 2013 and here it is October 2014. Incredible tale of what can go wrong when you're trying to start a startup. All the usual suspects: dodgy suppliers substituting cheaper, lower quality parts; huge blowout in shipping costs; China Post doing it's best to completely destroy itself by never actually shipping what they said they did.

Anyway here's my baby:
Here's some of my first experiments in extruding:
Here's why I have a lot to learn (that box corner is not meant to lift up):
And here's why the Rigidbot is an incredible kit. It can basically be assembled with one Allen key (supplied), but there's a couple of parts need smaller keys (also supplied). However, it also needs a mallet (not supplied) because some of the tubes/rods simply do not fit easily inside some of the plastic fittings.
Now I have to learn how to design parts from scratch as well as re-use existing designs. Thingiverse.com has a huge number of designs to start with. But I've also had to learn to use OpenSCAD to design the box. (I tried simply using a Gcode file offered here but the differences between Felix printers and Rigidbots are too great. And I also discovered there are no usable Gcode to STL converters any more. There might have been a couple of years ago but not maintained now.)

Then I had to learn about various slicers and dicers to generate Gcode from the design and upload the print task to the Rigidbot. Eventually settled on Repetier-Host for Mac for initial prototyping but also installed Octoprint on my RPi so I can offload print tasks to RPi while I continue with MacBook.


Friday, July 11, 2014

A DHCP client (fail?)

I was hoping to implement a DHCP client in the GA144 as mentioned in a previous blog. I'm more familiar with Perl than C these days so I downloaded the Net::DHCP::Packet module from CPAN and proceeded to use some of the examples to test out the DHCP server on my router. It's a lot easier to single-step through Perl code (for me at least) than using GDB on a compiled C program.

The sample dhcp daemon and test scripts work well. But when I tried talking to my router I was able to get a DHCPOFFER but was unable to get a DHCPACK reply. And even that would only work when I used the MAC address of my Mac(!). I couldn't use any other MAC address. I just don't know enough about DHCP to know if the router is acting correctly or not. The router's log says it receives the DHCP request and that it sends an OFFER and an ACK but the ACK packet doesn't seem to arrive. Possibly issues with firewalls etc.

There's a lot of code in Net::DHCP::Packet and it occurred to me that a DHCP client is not really necessary for this project. Nice to have but maybe not this iteration. I can load the IP address I've assigned to it using the code in the previous blog so there will be no conflict with my network devices.

So I'll proceed to step 2: a 'Hello world' server which simply sends the same reply to whatever inquiry it receives.


Tuesday, July 1, 2014

Make a PCB pt2

I received the parts for the GettingToBlinky PCB I talked about in a previous blog. And they sat there for over a week while I caught up with a few other tasks I had.

Today I felt like whiling away a couple of hours without straining my brain too much and building a Blinky device seemed like the perfect task. I love the smell of burning flux in the morning.

Despite all my mutterings about using solder paste, a pick and place tool and a heat gun, I realised the parts in this project are quite large. Certainly easy enough to see under a magnifying lamp to hand solder. So with help of some Blu-Tack to hold the board still and a bit more Blu-Tack on the end of a screwdriver to lift the components out of their containers and place them on the board I soldered it all together.

I started with the 7555 because it has the smallest pads and is in the centre of the board so I didn't want other components getting in the way. Then I added the diode, resistors and capacitor in that order. The LDR is actually a big large for the thru-holes I placed for it but long leads made it easy to get it into place.

So then it was time to solder the battery holder in place and finally we were ready to roll!

I inserted the battery after checking and re-checking the polarity and...

Nothing. No blinky!

I pulled out the battery just in case something was cooking and proceeded to measure every component and trace I could. Everything checked out.

So I re-inserted the battery and measured the voltage across pin 8 (Vdd) and pin 1 (GND) of the 7555. Nothing!

A bit closer inspection of the battery holder made me suspect that I might have some sort of short. So I partially inserted the battery and yay! blinky! But if I pushed the battery fully into the clip it stopped. But nothing was shorting. I looked at the battery and I looked at the board where it connects and it looks like the solder pad is too flat or the battery flexes slightly concavely at that point. Anyway the solution was obvious. I unsoldered the battery clip, added a large drop of solder to the GND pad on the board, resoldered the clip and reinserted the battery and yay! blinky! And I could push the battery fully into the clip now and it continues working.

Here's the "offending" centre GND pad:
I had to add a blob of solder to it to raise it's height enough to contact the battery negative. Here's the clip and battery in place:

And finally, Blinky!

Some lessons for the future

The blink rate is supposed to vary depending on how much light falls on the LDR. The GettingToBlinky tutorial left the actual value or even the range undisclosed. I picked a value at random from Digi-Key (16-33K) but this is probably way too low considering it's connected to a 470K resistor. Probably should have been 160-330K. No harm done but unless I knew the blink rate is supposed to vary, I probably wouldn't notice the slight change that does occur as I move the LDR from bright light to darkness.

The second lesson is far more serious, and potentially dangerous. The battery clip touches one of the LDR leads:
Fortuitously, this LDR lead actually does connect to the positive terminal of the battery and so no harm done. However the potential for disaster is quite obvious. And again the solution is so simple. I had plenty of room on the board to move the thru holes for the LDR away from the battery clip but I had left the outline of the original SMD version and not updated it to that of the thru hole version. As a result I didn't see the potential conflict.

Which brings me to the third lesson. I made the mistake with the LDR and battery clip placement because I purchased these components blind, relying on diagrams and data sheets. In all my years as an electrical engineer, I never did that. I always insisted on having the actual components in my hands so I could measure them myself and see how they all fitted together. Digi-Key and similar suppliers are wonders compared to the old days but the potential for mistakes seems to rise when one is relying solely on data sheets.

On the other hand, in this brave new world where I can design and have these boards built for AU$1.40 plus AU$3.00 for components each, I think I can live with the cost of ordering sight unseen. The savings in time and money is enormous.

So tomorrow I will try out reflow soldering with solder paste and a heat gun.

Sunday, June 29, 2014

Interfacing Wiz550io to GA144

(aka: An Internet music player pt4)

Spent a week writing some low-level Forth words (subroutines) to drive the SPI interface on the wiz550io. Then realised that most of them already exist in the ROMs included with nodes 705 and 008 on the GA144.

Most of my time was spent trying to understand the heaps of C code out there for Arduinos and other microcontrollers. Wiznet has released source code for its drivers and, because it has to cover all usage cases, it is incredibly detailed and wordy. I quickly decided that for the music player I would only ever be reading and writing multiple bytes so there is no need to handle the Fixed Data Modes. Likewise I will only be supplying a single response to any client request: a stream of HTTP packets containing MP3 data. (Although I will also add code to query the DHCP server and obtain an IP address.)

I'm slowly starting to appreciate how good ArrayForth is.

To put things in perspective, the C source code from Wiznet for use with Arduino comes to 2711 lines. Admittedly much of this is comments. The code below for the same basic functions comes to 78 lines of which about 50% is comments.

I had a couple of actual hardware issues. When I plugged in the Wiz550io, the 3.3v rail sank to 2.9v. I quickly realised that it isn't properly regulated. So I wired an el-cheapo buck regulator board into the 5v rail to supply 3.3v and it's rock solid now.

Another issue was that (I think) I was clocking the Wiz too fast. I copied an SPI routine in the ArrayForth example code for reading and writing flash RAM and it was written to maximize data transfer speeds. I changed the delay factor from 20 to 1000 and transfers seem very stable now.

Another issue was that I wasn't watching very carefully when I wrote the routine to write to the IO pins on the GA144 and wasn't giving it enough settling time. As a result I was getting occasional glitches on the chip select line. There are lots of warnings in the user guide and I fell straight into the trap. Simple solution is to add a couple of no-ops after the write.

The code below uses two GA144 nodes: node 705 because it and node 008 are the only nodes with all the i/o pins needed for SPI interfacing and node 706 because I didn't want to burden 705 with time-wasting code which varies the clock speed plus it makes it easier to separate the work load. Node 706 pre-shifts the write bytes before sending them to node 705. Meanwhile 705 can be getting on with the task of changing i/o pins levels and pausing to allow them to settle without holding up node 706.

Eventually I will need to rewrite code in 706 to read and write bytes from other nodes via 'wires' (same as used in musicbox).

Open Workbench Logic Sniffer

I used this US$50 16-channel logic analyser (and software) to follow the SPI bus exchanges and it has got to be the best value for money in the electronics world. Not only does it capture logic levels upto 50Mhz but the software also includes protocol analysers, including an SPI analyser.

The screenshot (click image to enlarge) shows node 705 sending a 4-byte IP address (192.168.1.228) to the wiz for loading into the device's Source IP Address registers (0x0f-0x12). It then reads the registers back and stores them in the data stack of node 706.

Pinging the Wiz550io

As luck would have it, my home LAN uses 192.168.1.xxx subnet and the default startup IP for the Wiz is 192.168.1.2 and it's otherwise unused on my LAN. So I plugged the Wiz into it's socket on the EVB001, turned on the 3.3v supply and plugged an Ethernet cable into it from the router. Then I ping'ed the IP address and the Wiz responded. I unplugged the Wiz and pinged again and nothing answered (so I knew there wasn't another device on the LAN with the same IP :). Similarly after running the code below to change the IP address of the Wiz I was again able to ping it at 192.168.1.228 confirming the SPI upload of the IP address.

Next tasks

So now I need to add the DHCP client and a simple HTTP 'Hello World' server before tackling the huge task of writing an MP3 encoder.

The code

1018 list 
spi interface to wiz550io
705 node 0 org
start 00 left a! io b!
2 20 1000 dup -++ half
nxt @ push ex . nxt ;
done 09 -++ !b . . ;
!8 8obits drop ;
!24 @ 8obits 0f !8 @ !8 ;
addsel
 11 dup select !24 ;
bytout
 13 @ for @ !8 next done ;
byte
 17 dup dup or 7 push ibits ;
bytin 1a @ for byte ! next done ; 1e
  
start init regs a and b. Load stack with delay factor. Set pins 1(CLK) and 3(CS) high and 5(MOSI) low
nxt read address of next word to run from left port, push into return stack and ex to jump to word.
done set cs and clk high.
!8 use rom word 8obits to clock out 8 bits in reg t.
!24 clock out 16 bits in t, drop t then clock 8 bits out of next stack word.
addsel enable cs pin 3 then clock out 24 bits to select address in wiz. Also set r/w bit.
bytout read num of bytes to output from left port, then clock each set of bits out.
byte clock 8 bits into reg t.
bytin read num of bytes to input from left port, input each byte then send it to left port.

1020 list 
drive spi 705 iface
706 node 0 org
lsh for 2* unext ;
cmd push 9 lsh pop 1 lsh
06 @p ! . ' addsel ' ! ! ;
wbyt 09 @p ! ' bytout '
   
dup ! for 9 lsh ! next ;
rbyt 10 @p ! ' bytin '
   
dup ! for @ unext ;
start 14 left a!
begin
   
4 f cmd
   
228 1 168 192 3 wbyt
   
0 f cmd
   
3 rbyt
   
warm
end 28
lsh left shift
cmd left shift block select byte 10 bits, left shift address offset word 2 bits then pass s and t to node 705 to clock the 24 bits out to wiz.
wbyt write n bytes out using node 705 bytout word. shift each byte left by 10 bits prior to passing to bytout.
rbyt read n bytes into data stack.
start set a to left port, write IP address to wiz register then read IP address back in to leave it on stack.

1428 list ROM code
spi boot top/bot
4 kind aa reset host
---
 2a lit ; do, ce-, clk
--+
 2b lit ;
+--
 3a lit ;
+-+
 3b lit ;
-++
 2f lit ; target
a1 org 1388 load relay
c2 org
8obits
 dw-dw' 7 for leap obit
                2* *next ;
ibit
 c7 dw-dw'
  
 @b . -if drop - 2* ;
   then drop 2* - ;
half
 ca dwc-dw !b over
   for . . unext ;
select
 cc dw-dw -++ half
                --+ half ;
obit
 d0 dw-dw then
  
 -if +-- half
       +-+ half ; then
rbit
 d5 dw-dw --- half
              --+ half ;
18ibits
 d9 d-dw dup 17 for push
ibits
 begin rbit ibit - next ;
u2/ 2/ 1ffff and ; e1
a9 org
a9  warm await ;
aa 1430 load the rest
c1


1014 list 
install via async bootstream
empty compile
streamer load framer load
async frame ae fram ;
wizspi align create
708 705 to
-1 ,

wizspi course
2 fh load frame stream

serial load -canon
a-com sport ! a-bps bps ! !nam
talk send
2 706 hook panel


1016 list 
705 +node 705 /ram 0 /p
706 +node 706 /ram 14 /p
2 0 705 hook                                            

Saturday, June 28, 2014

An Internet music player pt3

The three subprojects mentioned in previous posting can in fact be regarded as one project, viz., connect the Wiz550io to the GA144 and output the stream of PCM codes as a webserver response. Conversion to streamed MP3 is icing on the cake. Booting from Flash is additional icing. Designing and building a PCB to hold the circuit will be the icing, cream and two cherries on top.

I've added two headers to the EVB001 prototyping area and wired them to the SPI connections of node 705. Thankfully realised that Wiz550io uses 3.3v levels but node 705 pins are at 1.8v levels. So I wired one of the spare level converters into the path.

Running Wiz550io from 3.3v required me to add a 3.3v source. Using my Dangerous Prototypes ATX Breakout Board to supply the 3.3v, I also realised I could add a jumper to the 5v supply connection and remove the 5v wall wart I had been using.

So now, using the examples in Ch 9 of ArrayForth Users' Guide, I can switch on the SPI pins DO, CLK and CS and see 3.3v levels on the corresponding pins of the socket for the Wiz (MOSI, SCLK and SCSn). On the EVB001 these pins are hidden behind some selection logic but there are some test points on the board to verify the correct responses.

Next step is to write some code to run the Wiz550io from node 705. Need word to get an IP address from DHCP server on network (overriding default IP). Need word to echo text back to client.

Sunday, June 15, 2014

Make a PCB

As I noted in a previous blog I followed a YouTube tutorial on how to create a PCB with KiCAD. Having got that far I decided to order the boards from DirtyPCBs. AU$14 for 10 boards including postage is hard to beat.

The boards arrived last Thursday and they are beautiful! And red! (I had expected green.)

So I figured that having come this far I might as well complete the exercise.

Being too lazy to shop around I decided to use DigiKey to fulfill the Bill of Materials (BOM). For 10 boards the total came to AU$52 (plus $16 for solder paste).

The whole point of the PCB design was to use SMD components so I've also ordered various tools to assist SMD soldering. On ebay I bought a pick and place tool, hot air gun and USB microscope.

I'm not sure whether a stencil is needed but I want to try this. For the size of the board in this instance and the size of the components I suspect squeezing the solder paste from the tube will be sufficient.

I've been contemplating a toaster oven converted to reflow oven but it doesn't make much sense at this stage.