W14: Input Devices

Assignment

Design and build a wired &/or wireless network connecting at least two processors

Personal Goal

Check the current on the USB charger i recently built

Table of Contents


Input Devices

A few weeks ago, i buit a USB charging station for our Fablab’s booth at an arts festival. It features a 10A step-down converter (TI LMZ22010) to supply 4 USB ports with lots of power. The data pins on the USB connectors were configured so that two of the ports would allow Android devices to draw full current and two to allow the same thing to iOS devices.

It also contains a hall-effect based current sensor, that outputs a DC voltage corresponding to the current drawn, the Allegro ACS712. Let’s make a board that reads this voltage and displays some stats on an LCD, to see how much power our devices really draw.

Hardware

To read and disply the output from our USB charger, i design a really simple board:

  • ATTiny44
  • ISP header
  • An LED for debugging purposes
  • One analog in to read from our USB charger
  • Two digital I/Os to display some data on a serial LCD

Design

I am recently doing all my PCB designs on upverter.com. Its parts library is okay and it’s got that beautiful feature called “Parts Concierge” - people making component footprints for you, according to datasheets you submit. I was using it for one of the USB connectors. After swapping the part for a different model for the third time, it’s such a good feeling to have someone help you on that detailed work ;)

Production

I tried some Bungard Green Coat on this board, looks like i took a bit too much.

Software

The ATTiny44 provides only little space (4KB) for our code. Using the SoftSerial library in Arduino would already occupy more than half of the program memory. Because fighting for each single bit sucks, we’re gonna implement this in “bare C”.

Basic Test

Just a quick test upfront to see that the board is working and can be programmed – our good ole’ Blink sketch:

Serial Communication

For the serial communication i found a really small library on the internet. I had to shift the table for the timings a bit, so it would correctly work at 8 MHz. Otherwise, i would have had to set the baud rate to 19200 for it to actually talk at 9600.

Analog Input

With a little bit of testing and tweaking, i created two functions based on information from the Atmel datasheet and Neil’s example code:

/**
 * Enable the ADC, set mode and channel.
 */
void adc_init()
{
    ADMUX = (0 << REFS1) | (0 << REFS0)  // VCC ref
      | (0 << MUX5) | (0 << MUX4) | (0 << MUX3) | (0 << MUX2) | (1 << MUX1) | (1 << MUX0);  // PA3 (ADC3)
    ADCSRA = (1 << ADEN)  // enable
      | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);  // prescaler /128
}

/**
 * Read the ADC and return a 10-bit value as integer.
 *
 * @return int
 */
int adc_read()
{
    ADCSRA |= (1 << ADSC);  // initiate adc reading
    while (ADCSRA & (1 << ADSC));  // wait for completion

    byte less_significant = ADCL;  // Read ADC registers, ADCL has to be read first
    return less_significant | ADCH << 8;
}

So far so good…

Before actually hooking up the LCD, i first check if the analog values are read correctly by feeding a UART signal back to my computer through an ordinary FTDI cable. Later i will connect the Rx of the LCD to the microcontroller’s Tx pin, instead of the FTDI adapter’s Rx, that is connected right now.

I also implement a function to wrap the “protocol” that my LCD display understands. Before hooking up the LCD, i connect the FTDI adapter and inspect the output through miniterm.py.

/**
 * Print given string on given line of a 2x8-char
 * serial LCD from iteadstudio.com
 *
 * @param line Line number (0|1)
 * @param text
 */
void lcd_print(byte line, char text[8]) {
    // Go to start of line
    char start[6];
    sprintf(start, "sd%i,0;", line);
    print(start);

    // Clear line
    print("ss        ;");

    // Go to start again
    print(start);

    // Print actual message
    char message[11];
    sprintf(message, "ss%s;", text);
    print(message);
}

Where it failed

  • Mostly nothing on the LCD
  • Only occasional (even meaninful) output
  • Using a logic sniffer, i couldn’t detect any meaninful conversation going on at a common baud rate
  • Probably the different input voltage (3.3 from the FTDI cable vs 5 from the DC supply) made the internal oscillator behave differently
  • Also, the lack of a capacitor on the board’s VCC might bring in some trouble
  • Conclusion: Re-design the board, add external oscillator, add input capacitance
Pro tip: Choose a processor with hardware UART if your project requires UART ;)