Final Project – Knockdown warning indicator

 

Coming together (in a New York hotel room)

 

 

Anemometer – wind speed indicator.

 

I 3D printed the part from a model I made in Rhino, and mounted it on a 12v DC motor.

 

 

Inclinometer – step response based on TxRx, using a curved piece of hose and some copper strips.  I had initially planned on filling the ends with hot glue, but this slowed down the water movement considerably and thus reduced the effectiveness of the sensor, so I only partially filled them.  I mounted the tube on a piece of birch ply I cut out using the CNC 3-axis mill in the hobby shop.

 

 

I routed the edges of the milled piece using a table router, sanded by hand, and finished using a satin urethane gel.

 

 

 

 

Hooked this up to the hello.txrx.45 board and it worked beautifully.

 

 

I initially planned on using a Fabduino and running an LCD, but found myself spending a lot of time troubleshooting, so I decided to use the original board I designed for use with an accelerometer.  I figured it had 3 pins connected to a header, which also carried VCC and GND, so that should work.  It also already carried labeled warning LEDs for the three ranges of squall condidtions

 

 

Made up an acrylic housing using the laser cutter.

 

 

Now it all hinges on the code,  which IÕm still troubleshooting:

 

// Knockdown

// Cobbled together by Simon Colley

// This is meant to run on an ATMEL ATMega328

 

#include <avr/io.h>

#include <util/delay.h>

 

 

#define output(directions,pin) (directions |= pin) // set port direction for output //this block is same as neil's, except for the define inputs line , which I don't know whether I need

#define input(directions,pin) (directions &= (~pin)) // set port direction for input

#define set(port,pin) (port |= pin) // set port pin

#define clear(port,pin) (port &= (~pin)) // clear port pin

#define pin_test(pins,pin) (pins & pin) // test for port pin

#define bit_test(byte,bit) (byte & (1 << bit)) // test for bit set

 

#define bit_delay_time 100 // bit delay for 9600 with overhead

#define bit_delay() _delay_us(bit_delay_time) // RS232 bit delay

#define half_bit_delay() _delay_us(bit_delay_time/2) // RS232 half bit delay

#define settle_delay() _delay_us(100) // settle delay

#define char_delay() _delay_ms(10) // char delay

#define nloop 100 // loops to accumulate

 

#define serial_port PORTD // changed from Neil's, to suit an ATMEGA

#define serial_direction DDRD

#define serial_pin_out (1 << PD1)

#define transmit_port PORTC

#define transmit_direction DDRC

#define transmit_pin (1 << PC1)

 

#define anemometer_port PORTC //suspect this will need to be changed to a different port - can I have inputs and outputs at the same time?

 

#define anemometer_direction DDRC

 

#define anemometer1 (1 << PC0)

 

#define anemometer_pins PINC

 

 

//outputs = three LEDs

#define led_port PORTD

#define led_direction DDRD

#define sixty (1 << PD2)

#define fortyfive (1 << PD3)

#define thirty (1 << PD4)

 

#define led_delay() _delay_ms(100) // LED delay

#define PWM_delay() _delay_ms(1000) // PWM delay

 

void put_char(volatile unsigned char *port, unsigned char pin, char txchar) {

   //

   // This is all straight from Neil's hello.txrx.45 code

   //

   // send character in txchar on port pin

   //    assumes line driver (inverts bits)

   //

   // start bit

   //

   clear(*port,pin);

   bit_delay();

   //

   // unrolled loop to write data bits

   //

   if bit_test(txchar,0)

      set(*port,pin);

   else

      clear(*port,pin);

   bit_delay();

   if bit_test(txchar,1)

      set(*port,pin);

   else

      clear(*port,pin);

   bit_delay();

   if bit_test(txchar,2)

      set(*port,pin);

   else

      clear(*port,pin);

   bit_delay();

   if bit_test(txchar,3)

      set(*port,pin);

   else

      clear(*port,pin);

   bit_delay();

   if bit_test(txchar,4)

      set(*port,pin);

   else

      clear(*port,pin);

   bit_delay();

   if bit_test(txchar,5)

      set(*port,pin);

   else

      clear(*port,pin);

   bit_delay();

   if bit_test(txchar,6)

      set(*port,pin);

   else

      clear(*port,pin);

   bit_delay();

   if bit_test(txchar,7)

      set(*port,pin);

   else

      clear(*port,pin);

   bit_delay();

   //

   // stop bit

   //

   set(*port,pin);

   bit_delay();

   //

   // char delay

   //

   bit_delay();

   }

 

int main(void) {

   //

   // main

   //

   static unsigned char count;

   static uint16_t up,down;

   //

   // set clock divider to /1

   //

   CLKPR = (1 << CLKPCE);

   CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);

   //

   // initialize output pins

   //

   set(serial_port, serial_pin_out);

   output(serial_direction, serial_pin_out);

   clear(transmit_port, transmit_pin);

   output(transmit_direction, transmit_pin);

   //

   // init A/D

   //

   ADMUX = (0 << REFS2) | (0 << REFS1) | (0 << REFS0) // Vcc ref

      | (0 << ADLAR) // right adjust

      | (0 << MUX3) | (0 << MUX2) | (1 << MUX1) | (1 << MUX0); // PC0

   ADCSRA = (1 << ADEN) // enable

      | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // prescaler /128

   //

   //initialize the anemometer - This is stuff I've added.

 

   clear(anemometer_port, anemometer1);

 

   input(anemometer_direction, anemometer1);

   //

   // initialize the LEDs - added this also

 

    clear(led_port, sixty | fortyfive | thirty); // | is bitwise operation, || is logical OR

 

    output(led_direction, sixty | fortyfive | thirty);

 

                  set(led_port, sixty | fortyfive | thirty);

 

   //

   // main loop

   //

   while (1) {

      //

      // accumulate

      //

      up = 0;

      down = 0;

      for (count = 0; count < nloop; ++count) {

         //

         // settle, charge

         //

         settle_delay();

         set(transmit_port, transmit_pin);

         //

         // initiate conversion

         //

         ADCSRA |= (1 << ADSC);

         //

         // wait for completion

         //

         while (ADCSRA & (1 << ADSC))

            ;

         //

         // save result

         //

         up += ADC;

         //

         // settle, discharge

         //

         settle_delay();

         clear(transmit_port, transmit_pin);

         //

         // initiate conversion

         //

         ADCSRA |= (1 << ADSC);

         //

         // wait for completion

         //

         while (ADCSRA & (1 << ADSC))

            ;

         //

         // save result

         //

         down += ADC;

         }

      //

      // send framing

      //

      put_char(&serial_port, serial_pin_out, 1);

      char_delay();

      put_char(&serial_port, serial_pin_out, 2);

      char_delay();

      put_char(&serial_port, serial_pin_out, 3);

      char_delay();

      put_char(&serial_port, serial_pin_out, 4);

      //

      // send result

      //

      put_char(&serial_port, serial_pin_out, (up & 255));

      char_delay();

      put_char(&serial_port, serial_pin_out, ((up >> 8) & 255));

      char_delay();

      put_char(&serial_port, serial_pin_out, (down & 255));

      char_delay();

      put_char(&serial_port, serial_pin_out, ((down >> 8) & 255));

      char_delay();

      }

 

    // get anemometer values

    //

    //think

   

    if wind = 10 and angle = 5

      or if wind = 12 and angle = 10

      or if wind = 16 and angle = 15

      or if wind = 18 and angle = 20

      or if wind = 20 and angle = 25

      or if wind = 22 and angle = 30

      then

        clear(led_port,sixty); //otherwise turn it on!

 

                  PWM_delay();

 

                  set(led_port,sixty); //turn off

 

    else if wind = 15 and angle = 5

      or if wind = 20 and angle = 10

      or if wind = 24 and angle = 15

      or if wind = 27 and angle = 20

      or if wind = 30 and angle = 25

      or if wind = 32 and angle = 30

      then

        clear(led_port,fortyfive); //otherwise turn it on!

 

                  PWM_delay();

 

                  set(led_port,fortyfive); //turn off

                 

    else if wind = 15 and angle = 5

      or if wind = 20 and angle = 10

      or if wind = 24 and angle = 15

      or if wind = 27 and angle = 20

      or if wind = 30 and angle = 25

      or if wind = 32 and angle = 30

      then

        clear(led_port,thirty); //otherwise turn it on!

 

                  PWM_delay();

 

                  set(led_port,thirty); //turn off                     

   }