NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Project Help and Ideas » A small diagnostics helper...

September 16, 2009
by rusirius
rusirius's Avatar

I do some repair work for a local company... Mostly what I get in are various boards from some "chick counters" they have. Basically after chicks are hatched, each one after being sexed is sent down a chute where they pass through one of these counters... The counters aside from keeping track of the chicks, evens them out by placing 50 in the front of a box and 50 in the back... And of course making sure that each box contains exactly 100...

Since these things fail pretty frequently, and they were originally made by a company in France that's no longer around to support them, I get a lot of them to diagnose/repair...

One of the things that's helpful when diagnosing a problem is seeing exactly what it's current count is while it's running through a cycle... I've been meaning to whip together a couple 4511s (7-seg decoder) with displays to attach while looking at one, but was never really motivated enough to do it, so generally I've just always ended up looking at each pin and doing the add-up in my head... Rather annoying for certain problems...

Anyway... Since I got the kit a couple days ago (been wanting to get into microcontrollers for a while now and just never took the plunge) I figured I needed a "real" problem to address in attempting my first project...

So I figured why not... Eventually I'll probably tie in a few more things that might make diagnosing even easier yet, but for now this will be a tremendous help... In fact, I think I'm gonna fire up eagle and lay out a permanent version... Just because... ;)

So with all that said... Here's the synopsis followed by the code...

The project is simple at this point and I've commented the code pretty well, so it should be pretty easy to follow along... Nothing complex in there at all, but of course if you have any questions feel free to ask... Or suggestions for that matter!

It simply takes the 4 bits from a decimal counter that represents the 1's place of the count and and loads them up into an int. Then it does the same with the 4 bits from the 10's place (okay, technically also the 100's place at the moment the count rolls... ;)... Then it displays the current count on the LCD as well as the serial port...

Code follows:

    /**************************************************
     * counter_display.c                              *
     * -----------                                    *
     *                                                *
     * Tool used to help diagnose chick counters      *
     * manufactured by Breuil.                        *
     *                                                *
     * rusirius@rusirius.net                          *
     *                                                *                        
     * Revisions: First revision will simply display  *
     *            output of both binary counters.     *
     **************************************************/

    #define F_CPU 14745600

    #include <stdio.h>

    #include <avr/io.h>
    #include <avr/pgmspace.h>
    #include <inttypes.h>
    #include "../libnerdkits/lcd.h"
    #include "../libnerdkits/uart.h"

    // PIN DEFINITIONS:
    //
    // PB1 -- Bit 0 of 1's counter
    // PB2 -- Bit 1 of 1's counter
    // PB3 -- Bit 2 of 1's counter
    // PB4 -- Bit 3 of 1's counter
    // PC0 -- Bit 0 of 10's counter
    // PC1 -- Bit 1 of 10's counter
    // PC2 -- Bit 2 of 10's counter
    // PC3 -- Bit 3 of 10's counter

    // MASK DEFINITIONS:
    //
    #define DIG1 0x1E
    #define DIG10 0x0F

    int main() {

      // start up the LCD
      lcd_init();
      FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
      lcd_home();
      lcd_write_string(PSTR(" Chick Counter Diag "));
      lcd_line_two();

      // start up the serial port
      uart_init();
      FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
      stdin = stdout = &uart_stream;
      printf_P(PSTR("Chick Counter Diag\r\n"));

      // Define variables:

      // holder variables for counter digits.  1 is 1's place, 10 is 10's place.
      uint8_t digit1 = 0;
      uint8_t digit10 = 0;

      // Begin main program loop...
      while(1) {

        // Let's get the bits from the 1's place counter into our int...
        // note we have to shift the result since we started with PB1 not PB0
        digit1 = (PINB & DIG1)>>1;

        // and now for the bits from the 10's place counter...
        digit10 = (PINC & DIG10);

        // Now let's shove it out to the LCD...
        lcd_line_two();
        fprintf_P(&lcd_stream, PSTR("Current Count: %d%d"), digit10, digit1);

        // and now let's update our friends on the serial stream...
        // extra space on end is to "clear" extra digit when 100 is reached and rolled
        // space on front is just a pad to make it line up with header
        // I'm only sending a \r instead of the standard \r\n because I want to keep the
        // count updating on a single line of the term rather than spamming a continuous
        // roll when the counter is counting...
        printf_P(PSTR(" Current Count: %d%d \r"), digit10, digit1);

        // Two things... It's pointless to keep updating the LCD with the same data over and
        // over again... Plus, we don't want to flood tons of data over the serial link...
        // we could delay, but later routines may need to act on each count, etc.. Plus we want
        // the response to be as quick as possible, so instead we'll just monitor the counters
        // and only continue if one changes...
        // Also, since the 10's place CAN'T change without the 1's place changing, we only have 
        // to watch that one...

        // Later I'll add support to monitor the reset line just in case the 1's place is on zero
        // if the counters reset...

        while(digit1==(PINB & DIG1)>>1);

        // counter changed so let's do it over again...

      }

      return 0;
    }

Post a Reply

Please log in to post a reply.

Did you know that interrupts can be used to trigger pieces of code when events happen? Learn more...