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.

Everything Else » Starting from Scratch!

February 16, 2012
by TheUnfocusedOne
TheUnfocusedOne's Avatar

Hey Everyone,

I just finished the nerdkit guide, and I'm ready to start working with it to create cool new projects. There's only one problem; I don't know anything about electronics.

I decided to pick up the book Make:Electronics, since it is supposed to be a great introduction to basic electronic theory and circuit construction. I'm going to be working with this book, the kit it comes with, and my NerdKit to create fun little projects that others can try to improve their understanding of electronics, while furthering their microcontroller programming skills.

I'm creating this thread to keep tabs on my progress, and to ask question so I don't do something stupid and burn out my ATmega. Hopefully this thread will create some fun new small projects that novice electrical engineers like myself can try.

February 16, 2012
by hevans
(NerdKits Staff)

hevans's Avatar

Good luck! I look forward to seeing your progress.

Humberto

February 16, 2012
by Ralphxyz
Ralphxyz's Avatar

The thing about "most" electronics books is that they do not account for using a micro processor.

Using a micro processor you can do things in code that you would normally do with electronic components.

Often you can completely obliterate the need for "external electronic components" or just limit the need for them.

Anyway wish you well and hope this becomes an (almost said a) active thread.

Ralph

February 17, 2012
by TheUnfocusedOne
TheUnfocusedOne's Avatar

Ralph,

That actually doesn't bother me. We could setup a dialog where I post pictures of a simple to moderate difficulty circuit, and then we figure out a way to do the same circuit with some more advance functions using the microprocesser. I'd appreciate that just so I can see which specific componets can be replaced by a microcontroller.

February 17, 2012
by Ralphxyz
Ralphxyz's Avatar

TheUnfocusedOne, that's cool!!

That would be very interesting.

I can picture a LED blinker using a 555 timer versus using a mcu to start.

Then expand it to blinking 10 or more leds eventually you would run out of pins on the mcu and go to a shift register or port expander.

That would make a good illustration of your great concept.

Ralph

February 17, 2012
by TheUnfocusedOne
TheUnfocusedOne's Avatar

Ralph,

That LED blinker with the 555 timer actually one of the first experiments the book uses to demonstrate IC chips!

I'm glad I've piqued your interest, and I hope you'll check in regularly to see my progress and offer advice.

Thanks!

February 26, 2012
by Ralphxyz
Ralphxyz's Avatar

TheUnfocusedOne, another great example would be:

External Switch Debounce v/s Software Debounce in the mcu code!!

I hope you put some examples together this would be an asset in the Nerdkit Community Library.

Ralph

February 27, 2012
by TheUnfocusedOne
TheUnfocusedOne's Avatar

Ralph,

Sounds like a great idea! I got my new kit on Friday, but I haven't had a chance to play with it yet. The first few experiments are pretty basic, so I may omit them in the interest of space. One I get to functioning circuits, I'll try to throw my ATMega in the mix and see if I can do some interesting stuff.

Thanks for the interests so far!

Pics to come sometimes soon I hope.

February 27, 2012
by Ralphxyz
Ralphxyz's Avatar

Well I like your idea and might add a circuit or two of my own.

So far in my thoughts it seems that if you only want one of a circuit (say led) rather doing it with components or a mcu one way or another does not have an apparent avantage. It's when you want a multiple of components (leds) that the mcu appears to have a advantage.

Ralph

February 27, 2012
by TheUnfocusedOne
TheUnfocusedOne's Avatar

Ralph,

Sounds great. I just spent the evening burning out LEDs and zapping my tongue with a 9v battery. The book has been fun so far. Nothing interesting yet, unless someone can think of a cool way to intergrate a potentiometer into the MCU.

February 28, 2012
by Ralphxyz
Ralphxyz's Avatar

Well you could use the thermal sensor code with the potentiometer in place of the thermal sensor.

Then you have a variable ADC (Analog to Digital) signal at the mcu what would you like to do with it?

You could do variable PWM, lighting a LED as a very basic starting circuit.

The PWM would be based on the voltage seen on the ADC.

I hope others find this interesting, now with CircuitLab we can design and test our circuits in a browser that is so cool.

Ralph

February 28, 2012
by pcbolt
pcbolt's Avatar

Ralph -

Pretty cool. Thanks for the link.

March 02, 2012
by TheUnfocusedOne
TheUnfocusedOne's Avatar

Alright so it's been a slow week of progress, but I finally played around with my Make kit last night.

I think my first project will be really simple. I'm just going to hookup the pot to the nerd kit, and have it setup so that as I decrease the resistance, more LEDs light up. I'll be going through the ADC, and probably using the PC pins.

Is there an easy way to access the 10 bits being used by the ADC through the pins? It would be pretty cool to set something up where I could literally see which bits are on and off by representing them as LEDs. Might be a good project for people just starting out, since you'll be able to see how the ADC is working!

Code coming tonight I hope. It is Friday, so I'm not sure if I'll be staying home to work on it or not.

March 02, 2012
by Ralphxyz
Ralphxyz's Avatar

Now that would be interesting I'd like to see the ADC represented with LEDs.

Ralph

March 03, 2012
by TheUnfocusedOne
TheUnfocusedOne's Avatar

Alright, so I typed up a quick program that might do the LED bit reprensentation

I can't see to get it loaded onto my MCU though... It's getting stuck during the second reading phase. Here's what I'm seeing:

Connecting to programmer: . Found programmer: Id = "FDL v02"; type = S Software Version = 0.2; No Hardware Version given. Programmer supports auto addr increment. Programmer supports buffered memory access with buffersize=128 bytes.

Programmer supports the following devices: Device code: 0x35

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9406 avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed To disable this feature, specify the -D option. avrdude: erasing chip avrdude: reading input file "ADCBitRep.hex" avrdude: input file ADCBitRep.hex auto detected as Intel Hex avrdude: writing flash (7860 bytes):

Writing | ################################################## | 100% 8.36s

avrdude: 7860 bytes of flash written avrdude: verifying flash memory against ADCBitRep.hex: avrdude: load data flash data from input file ADCBitRep.hex: avrdude: input file ADCBitRep.hex auto detected as Intel Hex avrdude: input file ADCBitRep.hex contains 7860 bytes avrdude: reading on-chip flash data:

Reading | ############# | 26% 0.26savrdude: butterfly_recv(): programmer is not responding make: *** [ADCBitRep-upload] Error 1 brian-dimarcos-macbook:ADCBitRep briandimarco$

Someone help me out? I'll post my code in the next post

March 03, 2012
by TheUnfocusedOne
TheUnfocusedOne's Avatar

Here's what I got for a basic code. Like I said, haven't been able to test it out yet.

/*Brian DiMarco
 Coding made for the ADC which will us LEDs to represent the current bit configuation of the ADC
 March, 3, 2012
 */

/*Standard Heads, same as Temp Sensor*/
#define F_CPU 14745600

#include <stdio.h>
#include <math.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>

#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/uart.h"

/*Pin Definitions!

 PC0 - Input from the pot*/

uint16_t low_bits; /*Global variable that will hold the lower bits of the ADC*/
uint16_t high_bits; /*Global variable that will hold the high bits of the ADC*/

/********************************************************************************/

/*sets the 10 pins we'll need to output!*/

void pinsSetup()
{
    DDRC |= (1<<PC1);
    DDRC |= (1<<PC2);
    DDRC |= (1<<PC3);
    DDRC |= (1<<PC4);
    DDRC |= (1<<PC5);
    DDRB |= (1<<PB1);
    DDRB |= (1<<PB2);
    DDRB |= (1<<PB3);
    DDRB |= (1<<PB4);
    DDRB |= (1<<PB5);
}

/****************************************************************************/

/*starts up the ADC*/
void adc_init() {
    // set analog to digital converter
    // for external reference (5v), single ended input ADC0
    ADMUX = 0;

    // set analog to digital converter
    // to be enabled, with a clock prescale of 1/128
    // so that the ADC clock runs at 115.2kHz.
    ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);

    // fire a conversion just to get the ADC warmed up
    ADCSRA |= (1<<ADSC);
}

/*******************************************************************************/
/*reads from the ADC*/

uint16_t adc_read()
{
    /*wait till cleared*/
    while(ADCSRA & (1<<ADSC))
    {
        /*Read from ADCL/ADCH*/

        /*Will temp hold the ADCL and ADCH values until combined into result*/
        uint16_t temp1 = ADCL; 
        uint16_t temp2 = ADCH; 
        uint16_t result;

        result = temp1 + (temp2<<8);

        /*result will be a 10 bit number, since the ADC can hold 10 bits
         I'm going to assign the lower 5 bits to low_bits and the upper 5
         to high_bits
         I'm going to AND values that will trim 'result' to the right size for
         each variable*/

        /*Low bits = (result & 0000011111 (or 1F in hex)
         High bits = (result & 1111100000 (or 3E0 in hex)*/
        low_bits = (result & 0X1F);
        high_bits = (result & 0X3E0);

        ADCSRA |= (1<<ADSC);

        return result;
    }
}

int main()
{
    // start up the LCD
    lcd_init();
    FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
    lcd_home();

    // start up the Analog to Digital Converter
    adc_init();

    /*Set up all the pins*/
    pinsSetup();

    /*holder variables*/

    uint16_t last_sample = 0;
    double average_ADC;
    uint8_t i;

    while(1){
        /*taking 1000 samples*/
        average_ADC = 0.0;

        for(i=0; i<1000; i++)
        {
            last_sample = adc_read();
            average_ADC = average_ADC + last_sample/1000.0;
        }

        // write message to LCD
        lcd_home();
        lcd_write_string(PSTR("ACD value: "));
        lcd_write_int16(last_sample);
        lcd_write_string(PSTR(" of 1020   "));

        /*Set each setup of LEDs to the bit rep of the ADC*/
        PORTB |= low_bits;
        PORTC |= high_bits;

        /*int cross_fingers(luck)*/

    }

    return 0;
}

What's everyone think? I'm not sure that it'll work. I'll post a video is I can get it working!

March 03, 2012
by TheUnfocusedOne
TheUnfocusedOne's Avatar

Hate to make a third post in a row, but it's been an exciting morning.

I have been getting that upload problem intermitedly, so I'm not sure what the problem is.

I managed to upload the old temperature sensor to the MCU after a few wacks at it. I wired up a pot to where the temp prob would normally go, and started fittling with it. It worked! I upped the voltage and the output on the LCD changed accordingly. Apparently I went a little to hard with it, because at somepoint the LCD was getting to much power and it was getting to bright to read. Then I notied my pot was glowing red and smoldering. It's pretty much destroyed, I'm going to pitch it. I tried putting a resistor (1K) between PC0 and AREF to slow down the current, but I couldn't get enough juice going to the MCU to register anything (I think, I was using the same pot, so the pot might of just been cooked). This project seems like it might be worth while if I can get it working!

Suggestions are more than welcome. I'm still really new to programming, so I'm not sure if my program even makes sense. I wouldn't mind some input on wiring things up, since I think I had my first brush with electrical death this morning.

Fun way to start the morning for sure!

March 03, 2012
by Rick_S
Rick_S's Avatar

Can you show how you had everything wired?? Adjusting the input to one of the ADC pins should have absolutely NO bearing on your LCD brightness. Also, dealing with typical voltages with a NerdKit, you should not be able to burn out a properly wired potentiometer. Either a photo or schematic or even a point to point drawing of how you wired it would be good.

Rick

March 03, 2012
by Rick_S
Rick_S's Avatar

A typical wiring for a potentiometer would be like this:

Pot wiring

Where ADC goes to the ADC input pin of your choice. Typical value for the pot would be 10K or greater. Remeber, the pot is simply acting as a voltage divider.

Rick

March 03, 2012
by TheUnfocusedOne
TheUnfocusedOne's Avatar

Oops!!!

I have it set up (left to right) AREF - GND - PC0

That would be the source of my problem. We'll, this has been a good learning experience of what not to do.

Thanks Rick!

March 03, 2012
by Ralphxyz
Ralphxyz's Avatar

Just for the record "AREF" is the "Reference" voltage pin for the ADC!!

Ralph

March 03, 2012
by TheUnfocusedOne
TheUnfocusedOne's Avatar

I feel like your trying to make a bigger point than that. Can you elaborate a bit more?

Should I not be plugging into AREF?

March 03, 2012
by Rick_S
Rick_S's Avatar

With the pot wired the way you did, when the pot was turned all the way to one end, your 5v rail would be dead shorted to your gnd rail. Given enough current, it could burn up your pot. Your LCD getting "brighter" may be due to VCC dropping as you progressed to full dead short.

As for AREF, I think Ralph was just pointing out that AREF is the ADC Reference voltage and while in the case of the NK, it is tied to VCC so it is at the same level, it doesn't need to be. Tying to AREF is fine though and would actually be preferred in this situation since the input to the ADC should never exceed AREF. In that situation, just substitue the pin I called 5V in my little diagram to AREF.

Rick

March 03, 2012
by TheUnfocusedOne
TheUnfocusedOne's Avatar

Hmm, so I got it hooked up right and after a small bit of smoke due to my alligator clips touching (Doh!) I seem to be getting somewhere.

I can vary the ADC only slightly, and I don't seem to be able to have the LED reflect any changes. I change the code a bit, but I still haven't gotten anywhere.

Anyone see any glaring problems with my code?

March 03, 2012
by Ralphxyz
Ralphxyz's Avatar

Start out with just the Temp Sensor project code!!

With the pot between the +/- rails and the wiper to PC0 you should see between 0 and 1024 (or what ever the max is).

Then compare that code with your code.

To see the expected range you can also just wire the + rail to PC0 and then do the - rail.

That is just straight wiring with no pot and running the Temp Sensor code.

Ralph

March 12, 2012
by TheUnfocusedOne
TheUnfocusedOne's Avatar

Hey everyone,

So I spent some time yesterday planing around with my NerdKit trying to get this ADC representation working. I decided to go easier at first, and only represent the current state with two LEDs and work up from there. At some point, I manage to get my system to work so that it would more or less show the converted ADC (from 10 bits to 2 bits) of the system when I first plugged it in. It wouldn't change when I varied the pot, it would just stick on this first setting.

I don't have access to my code at the moment, but what I did to make this system is create a few different functions and had them in a while loop. The first simply obtained the ADC data (same as the temp program), the next took that value and converted it into a 0, 1, 2 or 3 based on the range that value fell into and the last function simply took that value and setup the LEDs using a switch function.

Probably not enough information, but anyone have any idea why my LEDs wouldn't actively change when I vary the voltage? I have everything in a while loop, so it should be updating the ADC value which could change everything else.

Thanks guys!

March 16, 2012
by TheUnfocusedOne
TheUnfocusedOne's Avatar

Okay all, here what my current code is:

/*
 *  LED ADC.c
 *  Jan2012
 *
 *  Created by Brian DiMarco on 3/11/12.
 *  Copyright 2012 Roger Williams University. All rights reserved.
 *  
 */

/*This program will convert a virtual ADC status to viewable format (LEDs)*/

#define F_CPU 14745600

#include <stdio.h>
#include <math.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>

#include "../libnerdkits/delay.h"

#define NUMBITS 4 /*the number of bits currently in the system. Currently 4 bit states, which means each bit
has a range of 256*/

void adc_init() {
    // set analog to digital converter
    // for external reference (5V), single ended input ADC0
    ADMUX = 0;

    // set analog to digital converter
    // to be enabled, with a clock precale of 1/128
    // so that the ADC clock runs at 115.2kHz
    ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);

    // fire a conversion just to ge the ADC warmed up
    ADCSRA |= (1<<ADSC);
}

/*function that will turn on port b to output*/

void port_B_Output() 
{
    DDRB |= (1<<PC1);
    DDRB |= (1<<PC3);
}

/*Function to read from the ADC*/

uint16_t adc_read() {
    while(ADCSRA & (1<<ADSC)){
    }
    /*put the current ADC value into result*/
    uint16_t result = ADCL;

    return result;
}

/*Function to evaluate which LED bits should be on or off by dividing the 1024 ADC bits by the number
 of LED states and returning a corresponding value for them*/

/*current - The current value at the ADC
  eval - holder value that will fed into an if-else thread that will evaluate which bits will be on
  i - the value returned*/
int adc_eval(uint16_t current)
{
    int eval;
    int i;

    eval = current;

    if(eval<=256)
        i = 0;
    else if((eval>256)&(eval<=512))
        i = 1;
    else if((eval>512)&(eval<=768))
        i = 2;
    else
        i = 3;

    return i;
}

/*functions that will setup the actual LED config*/

void led_config(int x)
{
    switch(x){
        case 0: //dec 0 is 00 binary
            PORTB &= ~(1<<PB1);
            PORTB &= ~(1<<PB3);
            break;
        case 1://dec 1 is 01 bin
            PORTB |= (1<<PB1);
            PORTB &= ~(1<<PC3);
            break;
        case 2://dec 2 = 10 bin
            PORTB &= ~(1<<PC1);
            PORTB |= (1<<PC3);
            break;
        case 3://dec 3 = 11 bin
            PORTB |= (1<<PC1);
            PORTB |= (1<<PC3);
            break;
        default: //if something is wrong, the other LED will light up letting me know so//
            PORTC |= (1<<PC5);
            delay_ms(500);
            PORTC &= ~(1<<PC5);
            delay_ms(500);
            break;
    }
}

int main()
{
    adc_init(); //turns on the ADC
    port_B_Output(); //gets the portB pins set to output
    DDRC |= (1<<PC5);//sets up the extra portC pin for the fail

    uint16_t last_sample;
    int ledstat;

    while(1){
            last_sample = adc_read(); //reads from the ADC
            ledstat = adc_eval(last_sample); //takes that value, evaluated it
            led_config(ledstat); //sets up the LEDs
    }

    return 0;

}

Still not working, anyone have any thoughts?

March 16, 2012
by pcbolt
pcbolt's Avatar

@ Unfocused

On lines 76 and 78 you have a single "&" between the two test conditions. I think you want "&&" for a comparison operator.

On line 55, you read only the result of the lower 8 bits of the 10-bit ADC value from ADCL. Nothing wrong with that in and of itself, but your looking for a range of 0 to 1028. The way you have it set up, you'll only get 0-255. Not only that but the spec sheet says unless you read ADCH , ADCL will never get updated. The tempsensor project reads both registers and combines them correctly. Just copy that code and you should be fine.

March 17, 2012
by Rick_S
Rick_S's Avatar

There is a way to do 8 bit on the ADC if that is what you desire.

The 1st step is to left adjust the ADC Data Registers by setting the ADLAR bit in the ADMUX register to 1. This would be done when setting your channel like this.

ADMUX = (1<<ADLAR) | 0   // 0 HERE REPRESENTS THE ADC CHANNEL

Doing this, the data for the ADC read will be left adjusted. So now if you want an 8 bit result, all you have to do in your adc_read function is read ADCH. ADCL can then be ignored. The new adc_read function would look something like this.

/*Function to read from the ADC when ADLAR is set to 1 (8 bit reading)*/

uint8_t adc_read() {
    while(ADCSRA & (1<<ADSC)){
    }
    /*put the current ADC value into result*/
    uint8_t result = ADCH;

    return result;
}

This will make your ADC reads 0 to 255. (Note I also changed the data types in the read function to 8 bit)

Otherwise, you will have to do as pcbolt said.

Rick

March 18, 2012
by TheUnfocusedOne
TheUnfocusedOne's Avatar

Make a lot of sense. I'm one my way back from an accepted students weekend at Johns Hopkins, so I'll give this a test once I get in.

Thanks guys.

March 18, 2012
by TheUnfocusedOne
TheUnfocusedOne's Avatar

It works! I decided to up the ante and made a three LED system. Here's my code:

/*
 *  LED ADC.c
 *  Jan2012
 *
 *  Created by Brian DiMarco on 3/11/12.
 *  Copyright 2012 Roger Williams University. All rights reserved.
 *  
 */

/*This program will convert a virtual ADC status to viewable format (LEDs)*/

#define F_CPU 14745600

#include <stdio.h>
#include <math.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>

#include "../libnerdkits/delay.h"

#define NUMBITS 4 /*the number of bits currently in the system. Currently 4 bit states, which means each bit
has a range of 256*/

/*These values are what the ADC will displaying
 This will make it easy to distinguish between values meant to be represented by the 
 LEDS or values utilized for just normal calculations*/

#define ZERO 0
#define ONE 1
#define TWO 2
#define THREE 3
#define FOUR 4
#define FIVE 5
#define SIX 6
#define SEVEN 7

void adc_init() {
    // set analog to digital converter
    // for external reference (5V), single ended input ADC0
    ADMUX = 0;

    // set analog to digital converter
    // to be enabled, with a clock precale of 1/128
    // so that the ADC clock runs at 115.2kHz
    ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);

    // fire a conversion just to ge the ADC warmed up
    ADCSRA |= (1<<ADSC);
}

/*function that will turn on port b to output*/

void port_B_Output() 
{
    DDRB |= (1<<PC1);
    DDRB |= (1<<PC3);
    DDRB |= (1<<PC5);
}

/*Function to read from the ADC*/

uint16_t adc_read() {
 // read from ADC, waiting for conversion to finish
 // (assumes someone else asked for a conversion.)
 // wait for it to be cleared
    while(ADCSRA & (1<<ADSC)) {
 // do nothing... just hold your breath.
 }
 // bit is cleared, so we have a result.

 // read from the ADCL/ADCH registers, and combine the result
 // Note: ADCL must be read first (datasheet pp. 259)
    uint16_t result = ADCL;
    uint16_t temp = ADCH;
    result = result + (temp<<8);

 // set ADSC bit to get the *next* conversion started
    ADCSRA |= (1<<ADSC);

    return result;
}

/*Function to evaluate which LED bits should be on or off by dividing the 1024 ADC bits by the number
 of LED states and returning a corresponding value for them*/

/*current - The current value at the ADC
  eval - holder value that will fed into an if-else thread that will evaluate which bits will be on
  i - the value returned*/

int adc_eval(uint16_t current)
{
    int eval;
    int i;

    eval = current;

    if(eval<=128)
        i = ZERO;
    else if((eval>128)&&(eval<=256))
        i = ONE;
    else if((eval>256)&&(eval<=384))
        i = TWO;
    else if((eval>384)&&(eval<=512))
        i = THREE;
    else if((eval>512)&&(eval<=640))
        i = FOUR;
    else if((eval>640)&&(eval<=768))
        i = FIVE;
    else if((eval>768)&&(eval<=896))
        i = SIX;
    else
        i = SEVEN;

    return i;
}

/*functions that will setup the actual LED config*/

void led_config(int x)
{
    switch(x){
        case ZERO: //dec 0 is 000 binary
            PORTB &= ~(1<<PB1);
            PORTB &= ~(1<<PB3);
            PORTB &= ~(1<<PB5);
            break;
        case ONE://dec 1 is 001 bin
            PORTB |= (1<<PB1);
            PORTB &= ~(1<<PB3);
            PORTB &= ~(1<<PB5);
            break;
        case TWO://dec 2 = 010 bin
            PORTB &= ~(1<<PB1);
            PORTB |= (1<<PB3);
            PORTB &= ~(1<<PB5);
            break;
        case THREE://dec 3 = 011 bin
            PORTB |= (1<<PB1);
            PORTB |= (1<<PB3);
            PORTB &= ~(1<<PB5);
            break;
        case FOUR: //dec 4 = 100
            PORTB &= ~(1<<PB1);
            PORTB &= ~(1<<PB3);
            PORTB |= (1<<PB5);
            break;
        case FIVE: //dec 5 = 101
            PORTB |= (1<<PB1);
            PORTB &= ~(1<<PB3);
            PORTB |= (1<<PB5);
            break;
        case SIX: //dec 6 = 110
            PORTB &= ~(1<<PB1);
            PORTB |= (1<<PB3);
            PORTB |= (1<<PB5);
            break;
        case SEVEN: //dec 7 = 111
            PORTB |= (1<<PB1);
            PORTB |= (1<<PB3);
            PORTB |= (1<<PB5);
            break;

        default: //if something is wrong, the other LED will light up letting me know so//
            PORTC |= (1<<PC5);
            delay_ms(500);
            PORTC &= ~(1<<PC5);
            delay_ms(500);
            break;
    }
}

int main()
{
    adc_init(); //turns on the ADC
    port_B_Output(); //gets the portB pins set to output
    DDRC |= (1<<PC5);//sets up the extra portC pin for the fail

    uint16_t last_sample;
    int ledstat;

    while(1){
            last_sample = adc_read(); //reads from the ADC
            ledstat = adc_eval(last_sample); //takes that value, evaluated it
            led_config(ledstat); //sets up the LEDs
    }

    return 0;

}

I'm planning on taking a video of it in action, hopefully tomorrow!

March 19, 2012
by pcbolt
pcbolt's Avatar

Glad to see it worked, and congrats on getting into Johns Hopkins. You must not be too unfocused to get into that place.

March 19, 2012
by pcbolt
pcbolt's Avatar

You could make the code more compact if you replace lines 94 through 174 with:

uint8_t adc_eval(uint16_t current){
    return (current / 128);
}

void led_config(uint8_t x){

    if (x > 7){
        PORTC |= (1<<PC5);
        delay_ms(500);
        PORTC &= ~(1<<PC5);
        delay_ms(500);
    }

    else {
        PORTB &= 0xD5;   // binary 11010101  turn off LED's 
        PORTB |= ((x & 4) << 3) + ((x & 2) << 2) + ((x & 1) << 1);
    }
}
March 20, 2012
by TheUnfocusedOne
TheUnfocusedOne's Avatar

Oh great, that make a ton of sense. I was trying to figure out the best way to scale this program. It makes perfect sense to just & the number to light up that bit bit with the current value.

Thanks PC!

March 31, 2012
by TheUnfocusedOne
TheUnfocusedOne's Avatar

Alright gents, I got a new problem for you guys.

I'm builing a circuit with a relay intergrated in it. I'm using a relay because I want to power a water pump that will be at 12V, so I don't want it direct contact with the MCU.

I'm building a system that will automatically fill a fishtank when the water level gets low, and will have button that will do an automatic water change.

So two questions. I have two small bread boards, one that I want running at 5v (for the MCU) and one at 12v (for the motor!). Can I use a single 12v plug to power everything? I was thinking that I would just use the voltage regulator (may need to buy one rated for that much voltage) to modify the voltage coming in from the 12v board to the 5v one. I'm worried that using a common ground will screw this system up, but I think I'm over thinking it.

Second, is there a simple way to set up the MCU so it wont do anything until I've held down a button for a few seconds?

Thanks guys.

March 31, 2012
by Ralphxyz
Ralphxyz's Avatar

Can I use a single 12v plug to power everything?

Yes

Second, is there a simple way to set up the MCU so it wont do anything until I've held down a button for a few seconds?

Well if you had a pin change interrupt the mcu could sit in a infinite loop doing nothing but looping until the button was pushed.

I had a 12 volt pump and some 5 volt solenoid valves being run by the mcu and had to have a common ground.

The mcu was powered, through a regulator, from the same 12 volts that ran the pump.

What are your concerns with a common ground?

Ralph

Post a Reply

Please log in to post a reply.

Did you know that a thermometer can be made "faster" by using a bit of math? Learn more...