Nov 15, 2011

2.4GHz (WiFi) Arduino Spectrum Analyzer - Part 3, CYWM6935 Wireless Radio Module


CYWM6935 Wireless Module

This module is the heart of the Spectrum Analyzer.  Since I "borrowed" the code from  Richi's Blog, I can't really explain how the code is working. But, it does work! Richi's code examples are available on github.

I fork from Richi's "Fritzing" picture example in my final prototype (no wiring picture available for that, see video below) in that I don't make any attempt at level shifting, I run my Atmega chip at 3.3V directly from a battery.

The tricky thing with the CYWM6935 is the spacing on the already-soldered pins - they're too narrow for standard 0.1" female jumpers that you may get from sparkfun or Pololu. For prototyping, I used some very narrow female-to-male jumpers from SchmartBoard, these worked great. In the finished product, I used narrow-spaced IDC 10-pin female header cable, similar to this one at sparkfun,  to connect up the CYM6935.
IDC 2x5 Pin Female Cable


Here's a video showing the transition from prototype to (more-or-less) finished product:







2.4GHz (WiFi) Arduino Spectrum Analyzer - Part 2, Display

As a practical approach to this project, I could have started with getting the CYWM6935 module working or testing out the graphical LCD. If I could not get either one working, I would have just stopped. There was code for both of these, but the Nokia LCDs had more examples and a simpler datasheet(!). I figured if I could get the LCD working and fail on the wireless module, I was still ahead. Graphical LCDs can be used in lots of projects.

My first step was to get a Nokia 3310 to play with. These are readily available on ebay and elsewhere for around $10. What you get is a faceplate, LCD on glass, and fine-pitched connections. The pads on the LCD normally are connected with Elastomeric (Zebra brand) connectors.


Click on picture to enlarge
Although I've soldered a fair number of kits and boards, I found it very difficult to wire connections to the 1.15mm pitch of the pads, but others have found workable solutions. I tried Starlino's approach of salvaging ribbon cable from an old DVD drive, but couldn't find cable that matched the pitch, it was off just a bit. Others have made breakout boards by etching purpose-built PCB's that change the pitch from 1.15mm to 2.54mm (0.1").

So it was off to ebay to see if I could find any clones of the Nokia 3310 LCD. The first one I found was this nice one from MDFly which came with a 10 pin 2mm pitch IDC connector for around $10.
The IDC ribbon connector was female on both ends, making it easier to use the 2mm pitch of the header: push one female end onto the keyed box header on the LCD's base, push thin male jumpers into the other end. After that, I could use the male jumpers to attach to a standard 0.1"/2.54mm spaced breadboard. OK! Progress.

However, this wasn't going to work well for me in my desired case. I wanted the smallest possible enclosure for the WiFi Analyzer, and the 10 pin IDC cable, folded over or turned into origami, would take up too much space. So it was back to ebay to see what else was available.
Found this Nokia 5110 clone from MIB Instruments, also available for about $10, free shipping from Hong Kong. The MIB Instruments N5110LCD has the same specs as the original Nokia 3310 and the MDFly versions: 84x48 pixels; uses Philips PCD8544 LCD controller; operates on 2.7V to 3.3V. What's nice for me is that the N5110LCD has 8 solder holes at the base of the unit, with standard 0.1"/2.54mm pitch. I could solder header pins onto the LCD. Those headers would fit into matching female headers soldered directly onto a PCB. That would save a lot of space from not having to route wires around.

Note: I used female headers to connect the LCD on my final hand-soldered board. I could have soldered the LCD headers straight onto the board and saved some vertical space. But I usually build my projects with reuse in mind. If the LCD is attached via female headers, I can easily remove it and use it somewhere else.


Another good source of Nokia 5110 LCD clones is adafruit.com. Included for the current $10 price is a level shifter. LadyAda has also written a nice, easy-to-use graphics library for these devices. Highly recommended!


2.4GHz (WiFi) Arduino Spectrum Analyzer - Part 1, Getting Started

Parts List:
Arduino seeedstudio clone
              OR
Parts for a minimal arduino:
  • A breadboard
  • 22 AWG wire
  • 7805 Voltage regulator
  • 2 LEDs
  • 2 220 Ohm resistors
  • 1 10k Ohm resistor
  • 2 10 uF capacitors
  • 16 MHz clock crystal
  • 2 22 pF capacitors
  • small momentary normally open ("off") button, i.e. Omron type B3F  
  • FTDI USB connector (for programming the Atmega micro)
  • 74HC4050 TTL Level Shifter
Plus: 
 




Minimal Arduino


If you'd like to get this working on a breadboard as a prototype, there's a good introduction to a minimal Arduino platform in an ITP Tutorial. One drawback of this approach is the need for some kind of programmer for the Atmega168/328 microcontroller, a tool to get code into the micro. This would be a one-time purchase that's reusable for other projects, but depending on your tool choice, would be around $20 USD. I mention the Arduino Breadboard because the ITP Tutorial has a good description of the layout of parts for a minimal Arduino. It's what I used as a basis for the layout of my own hand-soldered board. I then just added two other critical components, the graphical LCD and the Cypress Semiconductor CYWM6935 Wireless Radio Module, tied to the appropriate pins on the Atmega chip.

One advantage of the breadboard approach is that it's reusable for other projects. Also, unlike the approach shown below, you can swap in/out the Atmega chip in the circuit. That way, you could take another Atmega chip, load it up with a program on the breadboard, pop the newly-programmed chip out and put it into a separate, more permanent purpose-built circuit.

Getting to 3.3V
Electronic parts expect one of two different voltages to represent a digital 1 (on, or high): either 3.3v or 5V; digital 0 (off, or low) is represented by a voltage at or near zero. For this project, the LCD and CYWM6935 expect 3.3V logic as input but the board will be running at 5V, so we have to adjust the 5V down somehow. For this task, one integrated circuit you can use is a 74HC4050 Hex High-to-low level shifter ( I used an NTE4050B, available at my local Fry's). There are other approaches to this problem, but this is conceptually very simple: high voltage logic in one side, low voltage logic out the other.

For a digital logic signal from the 3.3V components, the Atmega168/328 is tolerant of 3.3V as a digital 1, so no special handling needed there.

At this point, you're looking at $10-15 for component parts; $5-8 for a breadboard; and maybe $20 for a programmer. And that's before you get to the key components, the LCD and CYWM6935, which are about $10 each.

Seeedstudio to the Rescue
Another option to drive the prototype is to use a seeedstudio Arduino clone, available for about $22.50 before S/H. The "seeeduino" clone has a switch to adjust the logic output to 3.3V or 5V and has worked fine for my prototyping. Expect about 14 business days after shipping to reach the U.S. A bonus for the seeeduino is that, in addition to female headers connected to the digital pins of the Atmega chip, as on the Arduino, there are through-hole solder points for each of the pins. That's useful in this project, because the LCD and CYWM6935 share some of the same connections, so you could have one component wired to the female headers and the other soldered to the through-holes. Or, solder additional female headers on the through-holes. You could build the entire project on the seeeduino, save some costs, and the basic parts costs would be about $45, including the LCD and CYWM6935.
Seeedstudio Seeeduino V2.2

Note that the seeeduino uses surface-mount versions of the Atmega chip. That means, unlike on an Arduino or your breadboard version, you can't pop out the Atmega chip (after loading your program code) and reuse it in a soldered, purpose-built version of your circuit.


2.4GHz Arduino Spectrum Analyzer - Overview

A while back, this work of Miguel Vallejo was featured on hackaday and other blogs. This was a Spectrum Analyzer for the ISM Band crammed into a repurposed Nokia 3410 cellphone. This intrigued me, I wanted to make one for myself.

The Journey is the Reward
I took this project on as a learning experience. I had never done anything this ambitious before, although I had soldered several kits from adafruit.com and had played with quite a few sketches on the arduino platform. Since electronics is a hobby for me, I choose what projects I'll undertake by at least three criteria, in descending order:
  1. how much I can learn from the effort?
  2. can the things I learn be extended to other projects?
  3. is the end product useful, novel or amusing in some way?
That last criteria, is the product useful, sometimes is not very important to me. I've often built things just to see that I can, or just to see what the gizmo does. For example, I love building computers. But when you're done, all you have is a computer ;-) !

What is important is the experience of building something, of facing challenges and answering them in a satisfying way. The main beginning goals of this project were to get some exposure to graphical LCDs and the wireless module, CYWM6935 from Cypress Semiconductor. A LOT of learning happened along the way and choices had to be made.

For the impatient, here's a video that shows the Spectrum Analyzer progressing from raw prototype to "Version 0.99 Beta", or close to "first engineering prototype". Video is about 2:07 in length:




Basic Parts Costs
Depending on how you choose to implement this project, your component and raw materials costs could be as little as about $30 USD, or over $50. That doesn't include additional tools like a breadboard or a microcontroller programmer, if you don't already have them.





Jul 25, 2011

Windows 7 Starting by Itself

Lately, every morning when I woke up, my wife's computer would have started up by itself from hibernation. In delving into the mystery, there are at least three mechanisms for waking:
  • Devices set to wake the computer
  • BIOS Setting
  • Windows Media Center update
The first thing I did was look at the BIOS settings. I found that the BIOS on this motherboard, an Asus P8H61, would not let me enter setup by pressing the DEL key on a USB keyboard. Never throw anything away! I had a PS/2 keyboard in inventory and that worked. I went into the APM section of the Advanced Tab in the BIOS and reviewed the various device settings. All were disabled.
Next, from a Command Line in Windows 7, I checked which devices were set to allow waking from sleep/hibernation. The command to do this is:
powercfg -devicequery wake_armed
This returned the following list:
USB Root Hub
HID compliant mouse
Realtek PCIe GBE Family Controller
HID Keyboard Device
ASMedia XHCI Controller
To reset these devices:
Start\Computer\Properties\Device Manager
Right-click on each device to get into its own properties (you may have to do several for the USB Root Hub). Click on Change Settings. You'll be prompted for the Administrator password. Click on the Power Management tab. Uncheck the "allow this device to wake the computer".
Problem solved!
I also checked on the Windows Media Center Update just to be sure. Click on this link for a how-to.





May 25, 2011

LCD 117, a little thinner

I really like the Modern Devices LCD serial backpack kit based on the work of P.H. Anderson. These boards allow you to connect a standard HD44780-controlled LCD to an arduino with just +V, GND and Tx from the arduino. The command set is easy to use and fairly broad.

The standard build on these kits connects the 117 to an LCD with female headers from the 117. For space constrained projects, though, I'd like the attached 117 as thin as possible.

I took a hint from the way Sparkfun implemented their version of the backpack. They soldered the backpack directly to the LCD headers, but not pushed all the way down. This way, the backpack is less thick, but won't short out by contacting the LCD board.

I emulated this by using a piece of closed-cell foam as a shim between the 117 and the LCD. I had to pull the foam out in pieces when done, but it worked.

The picture below shows the direct solder version on the right, the female header version on the left.



Image

May 12, 2011

Silverstone SG05 Sandy Bridge Build

My wife needed a faster computer but was space constrained where she could locate the box. The solution was to get a Silverstone SG05 mini-itx case , which included a 120mm front fan and a 300W small form factor PSU.

The motherboard I used was an Asus P8H61-I Rev 3 (http://www.newegg.com/Product/Product.aspx?Item%3DN82E16813131727&ved=0CBkQFj...) with an Intel i3-2120 Sandy Bridge processor.

Photo_1

Disassembling the combined optical drive and hard drive bay.

Photo_2

The space available for the motherboard.

Photo_3

Tight space in screwing down the mobo.

Photo_4

Motherboard with stock Intel HSF (plenty of clearance in my particular build) and memory installed.

Photo_5

Cable routing nightmare. I only installed a hard drive, no optical drive, and it was still a chore to arrange the cables from the PSU.
The build was actually straightforward, perhaps one of the easiest I've done lately. The box, with Ubuntu 10.04.2 LTS installed, runs fast and quiet.
Recommended.

Sent from my iPhone



Apr 24, 2011

Valentine's Heart with Fading/Blinking LEDs




Catching up on documenting old projects, this one from 2009.

The inspiration for this project was a posting from the good guys at NerdKits.
Humberto Evans gives a great tutorial on a Valentine's Day blinking heart, check it out along with the other great entries on their site.

I decided to try and make my own without the kit offered from the NerdKits folks. After a little research, I found alsmost all of the code I needed was available from Paul Badger of Modern Device, famous for the RBBB Arduino clone and other great products.


The actual base is just a sturdy piece of cardboard cut in the shape of a heart. There are heart templates easily found with a google search. I made an easel stand with another piece of cardboard properly cut at an angle. The code is running on a Modern Device RBBB Arduino, powering the LEDs through a black mini-breadboard that contains current-limiting resistors for the LEDS. The RBBB also prints a message on a 2x16 serial LCD. The 5mm red LEDs are poked through the base, hot-glued to the back. The wires are covered in heat shrink and then fastened in bundles with cable ties to make them neat.

The tricky part is keeping all of the LEDs in the proper order for sequencing the display. You may want to write down on the back of the heart which LED goes to which pin on the RBBB.

Code:
/* PWMallPins.pde
Paul Badger 2007
A program to illustrate one way to implement a PWM loop.
This program fades LED's on Arduino digital pins 2 through 13 in a sinewave pattern.
It could be modified to also modulate pins 0 & 1 and the analog pins.
I didn't modulate pins 0 & 1 just because of the hassle of disconnecting the LEDs on the RX and TX pins (0 & 1).

The PWM loop, as written, operates at about 175 HZ and is flicker-free.
The trick to this of course is not doing too much math in between the PWM loop cycles.
Long delays between the loops are going to show up as flicker. This is true especially of "Serial.print" debug statements
which seem to hog the processor during transmission. Shorter (timewise) statements will just dim the maximum brightness of the LED's.
There are a couple of lines of code (commented out) that implement a potentiometer as a speed control for the dimming.

How it works: The PWM loop turns on all LED's whose values are greater than 0 at the start of the PWM loop.
It then turns off the LED's as the loop variable is equal to the channel's PWM modulation value.
Because the values are limited to 255 (just by the table), all LED's are turned off at the end of the PWM loop.
This has the side effect of making any extra math, sensor reading. etc. will increase the "off" period of the LED's duty cycle. Consequently
the brightest LED value (255), which is supposed to represent a "100%" duty cycle (on all the time), dosesn't really do that.
More math, sensor reading etc will increase the "off time", dimming the LED's max brightness. You can (somewhat) make up for this dimming with
smaller series resistors, since LED's can be overrated if they aren't on all of the time.

The up side of this arrangement is that the LED's stay flicker free.
Note that this program could easily be used to modulate motor speeds with the addition of driver transistors or MOSFET's.
*/

// random fading in and out of
// christmas tree lights

#define NR_OF_LIGHTS 12
int pins[NR_OF_LIGHTS] = {2, 8, 6, 4, 12, 13, 10, 9, 7, 5, 3, 11 };

int values[NR_OF_LIGHTS];
int steps[NR_OF_LIGHTS];

#define NR_OF_FADESTEPS 4
int fadesteps[NR_OF_FADESTEPS] = { 192, 128, 64, 0 };
int fade_delay = 30; // millisec
int fade_cycles = 1000;

int nr_of_blinks = 2;
int blink_delay = 400; //millisec

int effect = 1;

int randomlights[NR_OF_LIGHTS];
bool chosenlights[NR_OF_LIGHTS];

int first_time = 1;


long time; // variable for speed debug
float pwmSpeed[14] = {
0, 0, 1.2, 1.3, 1.4, 1.9, .9, .8, .5, 1.2, 1.37, 1.47, .3, 3.2}; // these constants set the rate of dimming
int pwmVal[14]; // PWM values for 12 channels - 0 & 1 included but not used
float pwmFloats[14];
int i, j, k, l, x, y, z, bufsize, pot; // variables for various counters

unsigned char sinewave[] = //256 values
{
0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,

0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,

0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,

0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,

0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,

0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,

0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,

0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,

0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51,

0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,

0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a,

0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,

0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,

0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c,

0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c

};


void setup(){
pinMode(1, OUTPUT);
Serial.begin(9600);
Serial.print("?vmv4");
Serial.print("?G216");



DDRD=0xFC; // direction variable for port D - make em all outputs except serial pins 0 & 1
DDRB=0xFF; // direction variable for port B - all outputs

}

void fade_routine() {
// time = millis(); // this was to test the loop speed
// for (z=0; z<1000; z++){ // ditto // pot = analogRead(0); // this implemented a potentiometer speed control to control speed of fading for (y=0; y<14; y++){ // calculate one new pwm value every time through the control loop j = (j + 1) % 12; // calculate a new j every time - modulo operator makes it cycle back to 0 after 11 k = j + 2; // add 2 tp tje result - this yields a cycle of 2 to 13 for the channel (pin) select numbers pwmFloats[k] = (pwmFloats[k] + pwmSpeed[k]); // pwmFloats[k] = (pwmFloats[k] + ((pwmSpeed[k] * 15 * (float)pot) / 1023)); // implements potentiometer speed control - see line above if (pwmFloats[k] >= 256){ // wrop around sinewave table index values that are larger than 256
pwmFloats[k] = pwmFloats[k] - 256;
}
else if (pwmFloats[k] < 0){ pwmFloats[k] = pwmFloats[k] + 256; // wrop around sinewave table index values that are less than 0 } pwmVal[k] = sinewave[(int)pwmFloats[k]]; // convert the float value to an integer and get the value out of the sinewave index } PORTD = 0xFC; // all outputs except serial pins 0 & 1 PORTB = 0xFF; // turn on all pins of ports D & B for (z=0; z<3; z++){ // this loop just adds some more repetitions of the loop below to cut down on the time overhead of loop above // increase this until you start to preceive flicker - then back off - decrease for more responsive sensor input reads for (x=0; x<256; x++){ for( i=2; i<14; i++){ // start with 2 to avoid serial pins if (x == pwmVal[i]){ if (i < 8){ // corresponds to PORTD // bitshift a one into the proper bit then reverse the whole byte // equivalent to the line below but around 4 times faster // digitalWrite(i, LOW); PORTD = PORTD & (~(1 << i)); } else{ PORTB = PORTB & (~(1 << (i-8))); // corresponds to PORTB - same as digitalWrite(pin, LOW); - on Port B pins } } } } } } void setAllLights(int value) { for (int i = 0; i < NR_OF_LIGHTS; i++) { digitalWrite(pins[i], value); delay(150); digitalWrite(pins[i],0); } for (int i = NR_OF_LIGHTS; i>0; i--) {
digitalWrite(pins[i], value);
delay(150);
digitalWrite(pins[i],0);
}

for (int i = 6, j=7; i>0; i--, j++) {
digitalWrite(pins[i], value);
digitalWrite(pins[j], value);
delay(150);
digitalWrite(pins[i],0);
digitalWrite(pins[j],0);
}
for (int i = 0, j = 12; i < 7; i++, j--) { digitalWrite(pins[i], value); digitalWrite(pins[j], value); delay(150); digitalWrite(pins[i],0); digitalWrite(pins[j],0); } } /** * */ void blinkAll() { for (int i = 0; i < nr_of_blinks; i++) { setAllLights(1); delay(blink_delay); // setAllLights(0); // delay(blink_delay); } } void runningLight(int startvalue) { setAllLights(startvalue); for (int j = 0; j < 2; j++) { randomize(); for (int i = 0; i < NR_OF_LIGHTS; i++) { analogWrite(pins[randomlights[i]], 255 - startvalue); delay(200); analogWrite(pins[randomlights[i]], startvalue); } } } void randomize() { for (int i = 0; i < NR_OF_LIGHTS; i++) { chosenlights[i] = false; } //first one always ok int r = (int)random(NR_OF_LIGHTS); randomlights[0] = r; chosenlights[r] = true; //next 4 for (int i = 1; i < 5; i++) { while (true) { r = (int)random(NR_OF_LIGHTS); if (chosenlights[r] == false) { break; } } randomlights[i] = r; chosenlights[r] = true; } //last one for (int i = 0; i < NR_OF_LIGHTS; i++) { if (chosenlights[i] == false) { randomlights[5] = i; break; } } } void loop(){ DDRD=0xFC; // direction variable for port D - make em all outputs except serial pins 0 & 1 DDRB=0xFF; // direction variable for port B - all outputs for (int j = 0; j < fade_cycles; j++) { fade_routine(); } if (first_time) { Serial.print("?f"); //clear screen delay(1000); Serial.print("Happy Valentines"); Serial.print(" Love Bob "); first_time = 0; } if (effect == 1) { blinkAll(); effect = 1; } /* else if (effect == 2) { runningLight(0); effect = 3; } else if (effect == 3) { runningLight(255); effect = 1; } */ }

Valentine's Heart with Fading/Blinking LEDs


Catching up on documenting old projects, this one from 2009.
The inspiration for this project was a posting from the good guys at NerdKits.
Humberto Evans gives a great tutorial on a Valentine's Day blinking heart, check it out along with the other great entries on their site.
I decided to try and make my own without the kit offered from the NerdKits folks. After a little research, I found alsmost all of the code I needed was available from Paul Badger of Modern Device, famous for the RBBB Arduino clone and other great products.

Img_1706

The actual base is just a sturdy piece of cardboard cut in the shape of a heart. There are heart templates easily found with a google search. I made an easel stand with another piece of cardboard properly cut at an angle. The code is running on a Modern Device RBBB Arduino, powering the LEDs through a black mini-breadboard that contains current-limiting resistors for the LEDS. The RBBB also prints a message on a 2x16 serial LCD. The 5mm red LEDs are poked through the base, hot-glued to the back. The wires are covered in heat shrink and then fastened in bundles with cable ties to make them neat.
The tricky part is keeping all of the LEDs in the proper order for sequencing the display. You may want to write down on the back of the heart which LED goes to which pin on the RBBB.

Here's the code, hope posterous doesn't mess it up!
/*
 PWMallPins.pde
 Paul Badger 2007
 A program to illustrate one way to implement a PWM loop.
 This program fades LED's on Arduino digital pins 2 through 13 in a sinewave pattern.
 It could be modified to also modulate pins 0 & 1 and the analog pins.
 I didn't modulate pins 0 & 1 just because of the hassle of disconnecting the LEDs on the RX and TX pins (0 & 1).
 The PWM loop, as written, operates at about 175 HZ and is flicker-free.
 The trick to this of course is not doing too much math in between the PWM loop cycles.
 Long delays between the loops are going to show up as flicker. This is true especially of "Serial.print" debug statements
 which seem to hog the processor during transmission. Shorter (timewise) statements will just dim the maximum brightness of the LED's.
 There are a couple of lines of code (commented out) that implement a potentiometer as a speed control for the dimming.
 How it works: The PWM loop turns on all LED's whose values are greater than 0 at the start of the PWM loop.
 It then turns off the LED's as the loop variable is equal to the channel's PWM modulation value.
 Because the values are limited to 255 (just by the table), all LED's are turned off at the end of the PWM loop.
 This has the side effect of making any extra math, sensor reading. etc. will increase the "off" period of the LED's duty cycle. Consequently
 the brightest LED value (255), which is supposed to represent a "100%" duty cycle (on all the time), dosesn't really do that.
 More math, sensor reading etc will increase the "off time", dimming the LED's max brightness. You can (somewhat) make up for this dimming with
 smaller series resistors, since LED's can be overrated if they aren't on all of the time.
 The up side of this arrangement is that the LED's stay flicker free.
 Note that this program could easily be used to modulate motor speeds with the addition of driver transistors or MOSFET's.
 */
// random fading in and out of
// christmas tree lights
#define NR_OF_LIGHTS 12
int pins[NR_OF_LIGHTS] = {2, 8, 6, 4, 12, 13, 10, 9, 7, 5, 3, 11 };
int values[NR_OF_LIGHTS];
int steps[NR_OF_LIGHTS];
#define NR_OF_FADESTEPS 4
int fadesteps[NR_OF_FADESTEPS] = { 192, 128, 64, 0 };
int fade_delay = 30; // millisec
int fade_cycles = 1000;
int nr_of_blinks = 2;
int blink_delay = 400; //millisec
int effect = 1;
int randomlights[NR_OF_LIGHTS];
bool chosenlights[NR_OF_LIGHTS];
int first_time = 1;

long time;                                                                    // variable for speed debug
float pwmSpeed[14] = {
 0, 0, 1.2, 1.3, 1.4, 1.9, .9, .8, .5, 1.2, 1.37, 1.47, .3, 3.2};             // these constants set the rate of dimming
int pwmVal[14];                                                               // PWM values for 12 channels - 0 & 1 included but not used
float pwmFloats[14];
int i, j, k, l, x, y, z, bufsize, pot;                                        // variables for various counters
unsigned char sinewave[] =        //256 values
{
  0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,
  0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,
  0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,
  0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
  0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
  0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,
  0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
  0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51,
  0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,
  0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a,
  0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
  0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
  0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c,
  0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c
};

void setup(){
  pinMode(1, OUTPUT);
  Serial.begin(9600);
  Serial.print("?vmv4");
  Serial.print("?G216");


  DDRD=0xFC;      // direction variable for port D - make em all outputs except serial pins 0 & 1
  DDRB=0xFF;      // direction variable for port B - all outputs
}
void fade_routine() {
    // time = millis();               // this was to test the loop speed
  // for (z=0; z<1000; z++){        // ditto
  //  pot = analogRead(0);          // this implemented a potentiometer speed control to control speed of fading
  for (y=0; y<14; y++){             // calculate one new pwm value every time through the control loop
    j = (j + 1) % 12;              // calculate a new j every time - modulo operator makes it cycle back to 0 after 11
    k = j + 2;                      // add 2 tp tje result - this yields a cycle of 2 to 13 for the channel (pin) select numbers
    pwmFloats[k] =  (pwmFloats[k] + pwmSpeed[k]);
    // pwmFloats[k] =  (pwmFloats[k] + ((pwmSpeed[k]  * 15 * (float)pot) / 1023));    // implements potentiometer speed control - see line above
      if (pwmFloats[k] >= 256){                  // wrop around sinewave table index values that are larger than 256
      pwmFloats[k] = pwmFloats[k] - 256;
    }
    else if  (pwmFloats[k] < 0){
      pwmFloats[k] = pwmFloats[k] + 256;        // wrop around sinewave table index values that are less than 0
    }
    pwmVal[k] = sinewave[(int)pwmFloats[k]];                   // convert the float value to an integer and get the value out of the sinewave index
  }
  PORTD = 0xFC;              // all outputs except serial pins 0 & 1
  PORTB = 0xFF;              // turn on all pins of ports D & B
for (z=0; z<3; z++){         // this loop just adds some more repetitions of the loop below to cut down on the time overhead of loop above
                             // increase this until you start to preceive flicker - then back off - decrease for more responsive sensor input reads
  for (x=0; x<256; x++){
    for( i=2; i<14; i++){    // start with 2 to avoid serial pins
      if (x == pwmVal[i]){
        if (i < 8){    // corresponds to PORTD
          // bitshift a one into the proper bit then reverse the whole byte
          // equivalent to the line below but around 4 times faster
          // digitalWrite(i, LOW);
          PORTD = PORTD & (~(1 << i));
        }  
        else{  
          PORTB = PORTB & (~(1 << (i-8)));         // corresponds to PORTB - same as digitalWrite(pin, LOW); - on Port B pins
        }
      }
    }
  }
}
  }
void setAllLights(int value) {
  for (int i = 0; i < NR_OF_LIGHTS; i++) {
    digitalWrite(pins[i], value);
    delay(150);
    digitalWrite(pins[i],0);
  }
  for (int i = NR_OF_LIGHTS; i>0; i--) {
    digitalWrite(pins[i], value);
    delay(150);
    digitalWrite(pins[i],0);
  }
 
  for (int i = 6, j=7; i>0; i--, j++) {
    digitalWrite(pins[i], value);
    digitalWrite(pins[j], value);
    delay(150);
    digitalWrite(pins[i],0);
    digitalWrite(pins[j],0);
  }
 for (int i = 0, j = 12; i < 7; i++, j--) {
    digitalWrite(pins[i], value);
    digitalWrite(pins[j], value);
    delay(150);
    digitalWrite(pins[i],0);
     digitalWrite(pins[j],0);
  }
}
/**
 *
 */
void blinkAll() {
  for (int i = 0; i < nr_of_blinks; i++) {
    setAllLights(1);
    delay(blink_delay);
   // setAllLights(0);
   // delay(blink_delay);
  }
}

void runningLight(int startvalue) {
  setAllLights(startvalue);
  for (int j = 0; j < 2; j++) {
    randomize();
    for (int i = 0; i < NR_OF_LIGHTS; i++) {
    analogWrite(pins[randomlights[i]], 255 - startvalue);
    delay(200);
    analogWrite(pins[randomlights[i]], startvalue);
    }
  }
}
void randomize() {
  for (int i = 0; i < NR_OF_LIGHTS; i++) {
    chosenlights[i] = false;
  }
  //first one always ok
  int r = (int)random(NR_OF_LIGHTS);
  randomlights[0] = r;
  chosenlights[r] = true;
  //next 4
  for (int i = 1; i < 5; i++) {
    while (true) {
    r = (int)random(NR_OF_LIGHTS);
    if (chosenlights[r] == false) {
      break;
    }
    }
    randomlights[i] = r;
    chosenlights[r] = true;
  }
  //last one
  for (int i = 0; i < NR_OF_LIGHTS; i++) {
    if (chosenlights[i] == false) {
    randomlights[5] = i;
    break;
    }
  }
}

void loop(){
 
 
   DDRD=0xFC;      // direction variable for port D - make em all outputs except serial pins 0 & 1
  DDRB=0xFF;      // direction variable for port B - all outputs
   for (int j = 0; j < fade_cycles; j++) {
    fade_routine();
    }
  if (first_time) {
     Serial.print("?f");  //clear screen
    delay(1000);
    Serial.print("Happy Valentines");
    Serial.print("       Love Bob     ");
    first_time = 0;
  }
 
     
 
 
 
 
 if (effect == 1) {
    blinkAll();
    effect = 1;
  }
  /*
  else if (effect == 2) {
    runningLight(0);
    effect = 3;
  }
  else if (effect == 3) {
    runningLight(255);
    effect = 1;
  }
 */
 
}























































Mar 8, 2011

Adding Arrows and Text in Picasa (Windows)

When you double-click a photo in Picasa, the photo editing features are available. Included in the editing tools is text.
A hidden feature of text is the ability to create arrows with the Wingdings font. These arrows can be rotated, moved and resized easily.
I learned this from the following Picasa forum entry:
http://www.google.com/support/forum/p/Picasa/thread?tid=1f0325178bdbec6b&hl=en

Img_1599


Mar 7, 2011

Changing The iPod Nano 1st Gen Battery

There are lots of instructions in web pages and videos for swapping out your old iPod nano battery. I sourced this one from ConsoleZombie: . The instructions in this video describe how to separate the bottom metal case from the top black material by starting at the side of the case.
I thought it might be easier to pry open the bottom near the USB connector. Unfortunately, I started prying at what I thought was the metal seam separating the black from the silver part of the connector. Wrong! That is a single joined piece. You have to start prying at the bottom seam of the USB connector.
You may be able to see a few tiny gouges in this picture. That's where I made my mistake...

Nano_battery_case_v2_1_tip1


Feb 28, 2011

Desoldering? How about drilling those vias out?

I have to admit I'm not very good at desoldering filled in vias on circuit boards. I have a success ratio of about 50% so far. Sometimes these are adjacent to ground planes which make them especially difficult to desolder. The last major fail I had, I applied too much heat and actually ruined the solder pad hole so that no solder would adhere to it.
One tip I found on a forum was to use a mini drill, also known as a pin vise, to drill out these kinds of holes. This is about the same labor effort as desoldering, but I find I have much more control, especially if I use the smallest possible drill bit in the set to start and work up as needed.
The mini drill I use is a cheap ($4.99 as of this writing) Harbor Freight model. I've used it successfully on three desoldering projects and haven't failed yet.
Here's a picture of the Harbor Freight 6 piece mini drill set:
Hf_mini_drill


Feb 23, 2011

AVG and Microsoft Security Essentials

On an XP machine, had AVG Free installed and decided to change to Microsoft Security Essentials (MSSE). Uninstalled AVG with Add/Remove Programs and installed MSSE. That worked for awhile, until the first MSSE upgrade (not update) failed. Uninstalled MSSE, installed AVG 2011. AVG started throwing an error related to avgrsx.exe and MSVCR80.DLL.
Found out that AVG has become similar to Norton in that you need a removal tool (http://www.avg.com/us-en/download-tools) to completely uninstall it. In my case, the removal tool triggered a restart, then continued on to good finish after the reboot. I remembered one of the fixes for the MSSE problem was to completely uninstall any previously-installed anti-virus software and then try an MSSE install again. So I did.
Worked fine, running the AVG removal tool was the fix.

Sent from my iPhone

Feb 8, 2011

DD-WRT Wireless Slow? Try these out...

-Channel width to 40MHz
-Frame burst to enable
-Preamble to short
-Shortslot override to short
-WMM to enable
-No acknowledgement to disable
-CTS protection to auto
-Left/right antenna to auto
-Network mode to NG-Mixed
-ACK timing to 0 or 300
-Make sure security stays at WPA2-AES
-Select wireless channel manually picking the least used one

Jan 25, 2011

Arduino + Power Switch Tail Fountain Controller

Syncing Things Up

My wife and I recently put in some new landscaping in our front yard, including low-voltage lighting controlled by a transformer/controller housed in our garage. The lighting controller had some nice features: you could turn the lights on at dusk via an optional photoelectric cell, and then turn the lights off with a timer, also an extra option. That was ideal for us, on at sundown, off at 10:00 PM.

At the same time we also purchased a granite, Japanese-style fountain that had embedded LED lights at the fountain throat. This looks dramatic at night as the lights are bright and the water reflects the light and, as our landscaper said, "looks like white fire".

Fountain + LEDs on at Night

We wanted the fountain and lights to sync with the landscape lighting controller, on at dusk, off at 10:00 PM. The fountain had a separate power cord for the lights and another for the pump. The landscape controller already had the timing we wanted, so it would have been ideal to connect it to the fountain/lights. However, neither our landscaper nor us wanted to try jacking the power for the fountain/lights directly into a $350 controller and watch it fry.

We tried using some digital timers, but these had some drawbacks. The cheap ones we looked at used extra-small fonts on their LCD display and a non-intuitive programming/setup process. If you ever had to reprogram the device, it was back to studying the instructions. The one we did buy offered a manual on switch, which we liked. We wanted to be able to turn on the fountain independently of the landscape lights, too. However, with the small font size and a confusing system for indicating when you were on manual, it was a painful device to use.

So, what to do?

Solution #1 - OptoIsolator
I felt confident I could cobble together a solution to the problem using an arduino and some other components. I just had to do some research. The problem definition has three parts:
  1. Power control of the fountain
  2. Detect when the landscape controller is on/off
  3. Be able to turn on the fountain/LEDs independently of the landscape controller
The first thing I found was a Power Switch Tail over at adafruit.com. This is a 120V power source with a relay triggered by a +5v/40mA signal, very easy to use. Adafruit packages the PST with a transistor and resistor so you can wire it right up to a microcontroller.

Power Switch Tail

OK, that takes care of power control. How to signal when the landscape controller was on?
The first thing I experimented with was an optoisolator. Very simply, this is an LED on one side of a gap, with a light detector on the other all encased in a tiny, light-proof shell. When the LED gets a voltage, it goes on, triggering the light detector. It's a way to isolate circuits from each other as you might want to do when one circuit is 12-15V AC (landscape controller) and one is operating on 5V DC (arduino).

I experimented with an optoisolator, hooking it up first to our old landscape controller. OK, seems to work fine. Let's try it out on the real deal, the new controller. Aaaaah! Turn it off, turn it off! A light pall of rubbery-smelling magic smoke appeared. Now I've done it. Check the controller. Whew! Still works....

What I had done was filched a circuit from the web and failed to read it carefully enough. I missed a ground. Oops. Time to review. Get it working, but it's cycling through on/off cycles while the controller remains constantly on. Hmn. Off to various forums for tips on how to use optoisolators. Found out that there are "double" optoisolators made just for AC current, and I had been using a "single" made for DC current. The landscape controller, while low voltage, was AC. The DC optoisolators can work, but you need to add some parts to the circuit. The optoisolators made to work with AC have two LEDs, each one picking up part of the AC cycle. The repeated on/off behavior I was seeing was the unmodified DC optoisolator only one phase of the AC cycle.


Exploiting Simplicity
While doing my research, I saw a forum posting where someone wanted to tell when a circuit powered on. One of the replies was "stick a night light in there and put a photocell on it to tell when the light comes on." Then it hit me: the landscape controller HAD a light inside of it, a power-on light that only operated when power was applied to the lights. Perfect!

Just had to do a little experimentation to calibrate the arduino to the returned photocell values. When I got values that unequivocally indicated the landscape controller was on, I turned on the power switch tail from the arduino.

Photocell Mounted inside Landscape Controller

Fountain Controller I/O: from Photocell; to Power Switch Tail

The only other thing needed was to mount the arduino in a project box. I added an LED to indicate power on for the fountain/LEDs, and an LED to show power on for the landscape controller. Finally, I added a pushbutton to be able to turn the fountain/LEDs on independently of the landscape lights.

Fountain/LED Power On Controller

Now, the Hack-a-Day crowd will argue that using an arduino for this is massive overkill. True!
But you can never have enough overkill. Seriously, if I had better skills I could have just used a 555 timer triggered by the photocell. It would have been much cheaper. However, I had taken too much time figuring out how to get this working, I had a wife to keep happy, and I already had familiarity with arduino and knew I could get it done with that.

Arduino Code:

#include

int photocellPin = 0; // the cell and 10K pulldown are connected to a0
int photocellReading; // the analog reading from the sensor divider
//int optoPin = 9; // input from optoisloator/transformer
int pwrLED = 13; // Power on/off indicator light 0 = OFF; 1 = ON
int fountLED = 7; // Fountain on/off indicator light 0 = OFF; 1 = ON
int pushbutton = 5; // PushButton switch: Normally Open (0), when closed sends HIGH (1)
int transistor = 3; // Transistor 2N3904 or similar NPN attached through 10K-22K resistor
int pwr = 1; // Transformer State: Logic LOW (0) indicates ON; Logic HIGH (1) indicates OFF!
int prev_pwr = 1; // Previous power state, to detect change in power. Same logic as pwr
int fountain = 0; // Is the fountain on/off? 0 = OFF; 1 = ON
int pb = 0; // PushButton State: 0 = OFF; 1 = ON
int prev_pb = 0; // Previous PushButton State, to detect change in on/off

// Instantiate a Debounce object with a 20 millisecond debounce time
Debounce debouncer = Debounce( 20 , pushbutton);

void setup()
{

// pinMode(optoPin, INPUT);
// digitalWrite(optoPin, HIGH); // need to set pull-up resistor or values float!
pinMode(pwrLED, OUTPUT);
pinMode(fountLED, OUTPUT);
pinMode(transistor, OUTPUT);
Serial.begin(9600);
Serial.print("Starting...\n");

}


void loop()
{
//pwr = digitalRead(optoPin);

photocellReading = analogRead(photocellPin);

if (photocellReading >= 510)
pwr = 0; // POWER ON
else
pwr = 1; // POWER OFF


// Update the debouncer
debouncer.update();

// Get the update value
pb = debouncer.read();

if (pwr) // Logic 1 = POWER OFF
if (pb) // Pushbutton was pressed, Logic 1
if (prev_pb) // If it was ON, turn it OFF
{fountUpd(0);
prev_pb = 0;
}
else
{fountUpd(1); // If it was OFF, turn it ON
prev_pb = 1;
}
delay(100);

Serial.print("Pushbutton value is: ");
Serial.print(pb);
Serial.print("\n");


Serial.print("Power Setting = ");
Serial.print(pwr);
Serial.print("\n");

if (pwr != prev_pwr) // A change in power state occured
{prev_pwr = pwr;
if (!pwr) // Power was turned on
{fountUpd(1);
Serial.print("Power Detected!\n");
digitalWrite(pwrLED, HIGH);
}
else // Power was turned off
{fountUpd(0);
Serial.print("NO POWER!\n");
digitalWrite(pwrLED, LOW);
}
}
//delay(2000);

}
void fountUpd(int state) {
fountain = state;
digitalWrite(fountLED, state); // turn on fountain status LED
digitalWrite(transistor, state); // activate transistor for Power Switch Tail
}

Here's another example of this idea of "Exploiting Simplicity" : turning on/off a computer remotely via arduino hooked up to the computer power switch, grounding it out appropriately. Video by Mr. Hasselhoff of www.ZomgStuff.net



Update:
Checked into a 555 timer circuit that could do the same thing as the Arduino gadget I built:


The circuit on the left will use the presence of light as a trigger for the speaker to make a buzzing sound. As long as the photocell detects sufficient light, with sensitivity controlled by the 100k ohm potentiometer, the speaker will buzz. Using information from the circuit on the right, if you remove the 10u cap and speaker at pin 3 of the 555 in the Light Detector circuit and substitute in a 2.2k ohm resistor and an NPN transistor to drive your load, this modified circuit will work to trigger the Power Switch Tail. I tested this with a 2N3904 and it worked fine.

Jan 19, 2011

Unetbootin: Bootable Lunux on a USB Stick

Used Unetbootin to create a bootable USB flash drive of Jolicloud, a cloud-based version of Ubuntu. Jolicloud has its own USB creator app, but on Jolicloud 1.1 that version stops with the message "No drive selected". Unetbootin works well enough, but even that took me three tries. I was writing over a Ubuntu 8.10 install on the flash drive. What finally worked was using fdisk to remove the existing partition (vfat) and create an ext3 partition, followed by mkfs.ext3 /dev/sdb1 in this case.
See the docs at:
http://unetbootin.sourceforge.net/

Jan 13, 2011

Python+Arduino = Simple Twitter Search Client

There are lots of twitter/arduino mashup examples out on the web. Here's one that's pretty easy to put together.




Requirements:
  • computer running python + Twython, a python add-in for twitter
  • 20x4 serial-enabled LCD
  • an arduino or arduino clone
This was developed in Ubuntu 10.04 (Linux). I leave it as an exercise to the interested student to make this work on Windows or Mac.

Steps:
  1. Install python. You can do this from the Ubuntu Software Center.
  2. Install twython. Here's the source on github.
  3. Hook up your LCD to the arduino. Serial LCDs only need +5V, GND and digital signal to TX (outbound to LCD from arduino).
Notes:
  • I used the Modern Device LCD117 serial kit hooked up to a 20x4 LCD from an ebay seller. Another option is this one from sparkfun.com.
  • I used a seeedstudio seeeduino, an arduino clone. Serial TX to the arduino(the RX pin on the arduino) will cause a real arduino to auto-reset. The seeeduino has a switch for manual reset, which avoids the problem. Here's the comments from the arduino.cc site:

    This setup has other implications. When the Duemilanove is connected to either a computer running Mac OS X or Linux, it resets each time a connection is made to it from software (via USB). For the following half-second or so, the bootloader is running on the Duemilanove. While it is programmed to ignore malformed data (i.e. anything besides an upload of new code), it will intercept the first few bytes of data sent to the board after a connection is opened. If a sketch running on the board receives one-time configuration or other data when it first starts, make sure that the software with which it communicates waits a second after opening the connection and before sending this data.

    The Duemilanove contains a trace that can be cut to disable the auto-reset. The pads on either side of the trace can be soldered together to re-enable it. It's labeled "RESET-EN". You may also be able to disable the auto-reset by connecting a 110 ohm resistor from 5V to the reset line; see this forum thread for details.

Python code:
#!/usr/bin/env python
import feedparser
import time
import serial
from sys import stdout
ser = serial.Serial('/dev/ttyUSB0', 9600)

from twython import Twython
twitter = Twython()
while(1):
  time.sleep(5)
  search_results = twitter.searchTwitter(q="%23arduino",lang="en",rpp="1")
    # use '%23' to prefix hash tag
  for tweet in search_results["results"]:
      #print tweet["created_at"]
      #print tweet["from_user"]
      #print tweet["text"]
      to_arduino = tweet["from_user"]+": "+tweet["text"]
      #print to_arduino
      ser.write(to_arduino[0:80].encode('utf-8'))
      time.sleep(5)
      ser.write(to_arduino[80:159].encode('utf-8'))
      time.sleep(5)
#end of script

Arduino code:
/***************************************************************************
* Twitter search client. Can be modified to display other
* RSS feeds by changing the source python script.
* Expects data input to serial (RX on arduino) to be formatted
* for your display. This example used 20x4 LCD (20 chars x 4 lines).
*
* Tested to work with Modern Device LCD117 Serial Kit (phanderson product)
*
* This is really just a general serial receive and print routine
*
* thisoldgeek@gmail.com
* 01/13/2011
****************************************************************************/



byte incomingFeeds;
int i = 0;
char feed[180]; // current feed from RSS

void setup()
{Serial.begin(9600);
delay(100);
Serial.print("?c0"); // set no cursor
Serial.print("?f"); // clear screen
}

void loop()
{
i = 0;

while(Serial.available()) // are there any bytes on the serial port ???
{
incomingFeeds = Serial.read(); // one instance of feed
feed[i]=(byte(incomingFeeds)); // store the feed chars in an array
i++;
}
feed[i]='\0'; // need to end the string

if (strlen(feed) >= 1)
{ Serial.print("?f"); // clear screen
Serial.print(feed); // print all 4 lines.
//May need a different print rtn for other serial LCD's
}
delay(1000); // needs a delay or drops most of the characters from the sender
}

Jan 8, 2011

cupsd not starting? Try this...

My cupsd wasn't starting on boot, I'd always have to do:
sudo service cups restart
Make sure the only thing in /etc/network/interfaces is the following two lines:
auto lo
iface lo inet loopback

I had the definition of eth0 in there, turns out it was actually causing a problem. Eth0 also wasn't showing up in the network manager notification area from nm-applet, so I commented out the /etc/network/interfaces lines related to eth0 and set up an entry in network manager for the specific MAC address of the on-board ethernet with the same parameters that I had in /etc/network/interfaces.
Rebooted, seems to work.


Jan 4, 2011

Ubuntu 10.04 Update Flatlined (temporarily) my Ethernet Card

On my Biostar TH55B HD motherboard, I have on-board Ethernet connectivity. Did a kernel update on Jan 03, 2011 to the following:
 2.6.32-27-generic #49-Ubuntu SMP Thu Dec 2 00:51:09 UTC 2010 x86_64 GNU/Linux
The update wanted a restart, so I did. No connectivity after that.
Hmn....
Well, let's see if it's hardware or software. This box dual-boots Windows 7 and Ubuntu 10.04 64 bit LTS. Boot Windows 7, LAN connectivity works just fine. OK, let's go back to Ubuntu and start troubleshooting.
Works fine in Ubuntu now. Go figure.