{"id":108,"date":"2011-05-22T13:51:12","date_gmt":"2011-05-22T21:51:12","guid":{"rendered":"http:\/\/www.icismachine.com\/blog\/?page_id=108"},"modified":"2011-07-15T18:16:49","modified_gmt":"2011-07-16T02:16:49","slug":"microcontrolled-simple-pulsating-led","status":"publish","type":"page","link":"http:\/\/www.icismachine.com\/blog\/projects\/microcontrolled-simple-pulsating-led\/","title":{"rendered":"Microcontrolled Simple Pulsating LED"},"content":{"rendered":"<p>A project that was long over due from a friend and with my costume for a show coming, I needed to sit down and just do it.<br \/>\n<object width=\"400\" height=\"300\"><param name=\"flashvars\" value=\"offsite=true&#038;lang=en-us&#038;page_show_url=%2Fphotos%2Ficis_machine%2Fsets%2F72157626838969814%2Fshow%2F&#038;page_show_back_url=%2Fphotos%2Ficis_machine%2Fsets%2F72157626838969814%2F&#038;set_id=72157626838969814&#038;jump_to=\"><\/param><param name=\"movie\" value=\"http:\/\/www.flickr.com\/apps\/slideshow\/show.swf?v=71649\"><\/param><param name=\"allowFullScreen\" value=\"true\"><\/param><embed type=\"application\/x-shockwave-flash\" src=\"http:\/\/www.flickr.com\/apps\/slideshow\/show.swf?v=71649\" allowFullScreen=\"true\" flashvars=\"offsite=true&#038;lang=en-us&#038;page_show_url=%2Fphotos%2Ficis_machine%2Fsets%2F72157626838969814%2Fshow%2F&#038;page_show_back_url=%2Fphotos%2Ficis_machine%2Fsets%2F72157626838969814%2F&#038;set_id=72157626838969814&#038;jump_to=\" width=\"400\" height=\"300\"><\/embed><\/object><\/p>\n<p>Below is information about the hardware, schematics, and code you will need to create this project. Let me know what you think.<\/p>\n<p>Materials:<\/p>\n<ul>\n<li>ATmega88 with ATMega-lite proto board from <a href=\"http:\/\/GizmosUSA.com\">GizmosUSA.com<\/a> that I received at the Fall Combots.<\/li>\n<li>SFH 310 FA phototransitor<\/li>\n<li>Some resistors, 1k, and either 2- 100k Ohm trim pot or a collection to swap in and out<\/li>\n<li>LED, in your favorite color and brightness and 1 more if you want an indicator light<\/li>\n<li>2 -.1uF cap<\/li>\n<li>CR2032 battery and battery holder<\/li>\n<li>10uH inductor, for the analog power side of the ATMega<\/li>\n<li>various jumper wires<\/li>\n<li>A MKII ISP programmer for your AVR (may need a seperate setup to program)<\/li>\n<li>AVRstudio<\/li>\n<li>optional &#8211; an Altoids tin for your project.<\/li>\n<\/ul>\n<p>Schematic is here -&gt;<a href=\"http:\/\/www.icismachine.com\/blog\/wp-content\/uploads\/2011\/05\/TwinkleStar.pdf\">TwinkleStar Schematic<\/a><\/p>\n<p>Code is really simple and based on AVR demo included in AVR studio :<br \/>\n<!--more--><br \/>\n<strong>main.c:<\/strong><\/p>\n<table border=\"1\" bgcolor=\"#FF0000\">\n<tr>\n<code><br \/>\n\/*<br \/>\n * ----------------------------------------------------------------------------<br \/>\n * \"THE BEER-WARE LICENSE\" (Revision 42):<br \/>\n * <joerg@FreeBSD.ORG> wrote this file.  As long as you retain this notice you<br \/>\n * can do whatever you want with this stuff. If we meet some day, and you think<br \/>\n * this stuff is worth it, you can buy me a beer in return.        Joerg Wunsch<br \/>\n * ----------------------------------------------------------------------------<br \/>\n *<br \/>\n * Simple AVR demonstration.  Controls a LED that can be directly<br \/>\n * connected from OC1\/OC1A to GND.  The brightness of the LED is<br \/>\n * controlled with the PWM.  After each period of the PWM, the PWM<br \/>\n * value is either incremented or decremented, that's all.<br \/>\n *<br \/>\n * This code allows for the pulsating behavior above only when the<br \/>\n *\tADC0 (sensor) < ADC5 (threshold )\n * Otherwise it it activates a steady LED on PORTB.1.\n *\/\n\n#include <inttypes.h><br \/>\n#include <avr\/io.h><br \/>\n#include <avr\/interrupt.h><br \/>\n#include <avr\/sleep.h><\/p>\n<p>#include \"iocompat.h\"<br \/>\n#include \"adc.h\"<\/p>\n<p>extern unsigned char LowLightFlag;<\/p>\n<p>enum { UP, DOWN };<\/p>\n<p>static uint8_t adder[2] = {2, 1};<br \/>\nstatic uint16_t pwm[2];<br \/>\nstatic uint8_t direction[2];<\/p>\n<p>\/*<br \/>\nTimer1 Overflow ISRs<\/p>\n<p>This ISR will handle multple (2 right now) LEDS via GPIOs<br \/>\n*\/<br \/>\nISR (TIMER1_OVF_vect)<br \/>\n{<\/p>\n<p>\tif (LowLightFlag)<br \/>\n\t{<\/p>\n<p>\t\t    switch (direction[0])<br \/>\n\t\t    {<br \/>\n\t\t        case UP:<br \/>\n\t\t            if ((pwm[0] += adder[0]) >= TIMER1_TOP)<br \/>\n\t\t                direction[0] = DOWN;<br \/>\n\t\t            break;<\/p>\n<p>\t\t        case DOWN:<br \/>\n\t\t            if (pwm[0]-- == 0)<br \/>\n\t\t                direction[0] = UP;<br \/>\n\t\t            break;<br \/>\n\t\t    }<\/p>\n<p>\tOCR1A = pwm[0];<br \/>\n\tPORTB &= ~0x1;<\/p>\n<p>\t}<br \/>\n\telse<br \/>\n\t{<br \/>\n\t\t\/\/turn off pulsating LED<br \/>\n\t\t\/\/Hold Red LED steady<br \/>\n\t\tdirection[0]   = UP;<br \/>\n\t\tpwm[0]  = 0;<br \/>\n\t\tOCR1A = pwm[0];<br \/>\n\t\tPORTB |= 0x1;<\/p>\n<p>\t}<\/p>\n<p>}<\/p>\n<p>\/\/ Peripheral intialization<br \/>\nvoid Timer1Init (void)\t\t\t\/* Note [6] *\/<br \/>\n{<br \/>\n    \/* Timer 1 is 10-bit PWM (8-bit PWM on some ATtinys). *\/<br \/>\n    TCCR1A = TIMER1_PWM_INIT;<\/p>\n<p>    \/*<br \/>\n     * Start timer 1.<br \/>\n     *<br \/>\n     * NB: TCCR1A and TCCR1B could actually be the same register, so<br \/>\n     * take care to not clobber it.<br \/>\n     *\/<br \/>\n    TCCR1B |= TIMER1_CLOCKSOURCE;<br \/>\n    \/*<br \/>\n     * Run any device-dependent timer 1 setup hook if present.<br \/>\n     *\/<br \/>\n#if defined(TIMER1_SETUP_HOOK)<br \/>\n    TIMER1_SETUP_HOOK();<br \/>\n#endif<\/p>\n<p>    \/* Set PWM value to 0. *\/<br \/>\n    OCR1A = 0;<\/p>\n<p>    \/* Enable OC1 as output. *\/<br \/>\n    DDROC = _BV (OC1);<\/p>\n<p>    \/\/setup output LED  for ADC<br \/>\n    PORTB = 0xFF;<br \/>\n    DDRB = 0xFF;<\/p>\n<p>    TIMSK1=0x24;<br \/>\n    TCCR1B=0xC1;<\/p>\n<p>\t\/* Enable timer 1 overflow interrupt. *\/<br \/>\n    TIMSK1 = _BV (TOIE1);<\/p>\n<p>}<\/p>\n<p>void HWInit(void)<br \/>\n{<br \/>\n    Timer1Init();<br \/>\n    ADCSetup();<br \/>\n    sei ();<br \/>\n}<\/p>\n<p>int<br \/>\nmain (void)<br \/>\n{<\/p>\n<p>    HWInit ();<\/p>\n<p>    \/* loop forever, the interrupts are doing the rest *\/<\/p>\n<p>    for (;;)\t\t\t\/* Note [7] *\/<br \/>\n        sleep_mode();<\/p>\n<p>    return (0);<br \/>\n}<br \/>\n<\/code><br \/>\n  <\/tr>\n<\/table>\n<table border=\"1\" bgcolor=\"#00FF00\">\n<tr>\n<strong>adc.h<\/strong><br \/>\n<code><br \/>\n#define ADC_PORT0 0<br \/>\n#define ADC_PORT1 1<br \/>\n#define ADC_PORT2 2<br \/>\n#define ADC_PORT3 3<br \/>\n#define ADC_PORT4 4<br \/>\n#define ADC_PORT5 5<br \/>\n#define ADC_PORT6 6<\/p>\n<p>#define LIGHTSENSOR ADC_PORT0<br \/>\n#define LIGHTTHRESHOLD ADC_PORT5 <\/p>\n<p>void ADCSetup();<br \/>\n<\/code><br \/>\n  <\/tr>\n<\/table>\n<table border=\"1\" bgcolor=\"#00FF00\">\n<tr>\n<strong>adc.c:<\/strong><br \/>\n<code><br \/>\n#include <stdio.h><br \/>\n#include <stdlib.h><br \/>\n#include <inttypes.h><br \/>\n#include <avr\/io.h><br \/>\n#include <avr\/interrupt.h><br \/>\n#include <avr\/pgmspace.h><br \/>\n#include <avr\/sleep.h><\/p>\n<p>#include \"adc.h\"<\/p>\n<p>static unsigned short LightSensorLevel = 600; \/\/get light level from adc0<br \/>\nstatic unsigned short LightThresholdLevel = 0; \/\/get threshold from adc5<\/p>\n<p>\/\/ aref is used should be the same as vcc<br \/>\n\/\/ prescaler of 2<br \/>\n\/\/ free running mode<br \/>\n\/\/ switch between adc0 and adc5<br \/>\nvoid ADCSetup()<br \/>\n{<\/p>\n<p>\tADCSRA = (1<<ADEN) | (1<<ADIE);\n\tADCSRB = 0;\n\tADMUX = 0; \/\/start with LIGHTSENSOR\/adc0\n\tDIDR0 =  0;\n\n}\n\n\n\n\nunsigned char LowLightFlag = 0;\n\/\/*****************************************************************************\n\/\/\n\/\/  ADC conversion complete service routine  \n\/\/\n\/\/*****************************************************************************\nISR(ADC_vect)\n{\n\tstatic unsigned short adc_value;\n\tadc_value = ADCL;   \n\t\/*shift from low level to high level ADC, from 8bit to 10bit*\/\n\tadc_value += (ADCH<<8);\n\n\n\n\t\/\/switch to different adc channel\n\tuint16_t temp = ADMUX&#038;0x0F;\n\n\tswitch (temp)\n\t{\n\n\tcase LIGHTSENSOR:\n\t\tLightSensorLevel = adc_value;\n\t\tADMUX=(ADMUX&#038;0xF0)| LIGHTTHRESHOLD;\n\t\tbreak;\n\tdefault:\n\tcase LIGHTTHRESHOLD:\n\t\tLightThresholdLevel = adc_value;\n\t\tADMUX=(ADMUX&#038;0xF0)| LIGHTSENSOR;\n\t\tbreak;\n\n\t}\n\n\tif (LightSensorLevel > LightThresholdLevel)<br \/>\n\t\tLowLightFlag = 0; \/\/light is on<br \/>\n\telse LowLightFlag = 1; \/\/light is off<br \/>\n}<br \/>\n<\/code><\/p>\n<\/tr>\n<\/table>\n","protected":false},"excerpt":{"rendered":"<p>A project that was long over due from a friend and with my costume for a show coming, I needed to sit down and just do it. Below is information about the hardware, schematics, and code you will need to create this project. Let me know what you think. Materials: ATmega88 with ATMega-lite proto board [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":15,"menu_order":0,"comment_status":"open","ping_status":"open","template":"","meta":{"footnotes":""},"class_list":["post-108","page","type-page","status-publish","hentry","entry"],"_links":{"self":[{"href":"http:\/\/www.icismachine.com\/blog\/wp-json\/wp\/v2\/pages\/108","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.icismachine.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"http:\/\/www.icismachine.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"http:\/\/www.icismachine.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.icismachine.com\/blog\/wp-json\/wp\/v2\/comments?post=108"}],"version-history":[{"count":0,"href":"http:\/\/www.icismachine.com\/blog\/wp-json\/wp\/v2\/pages\/108\/revisions"}],"up":[{"embeddable":true,"href":"http:\/\/www.icismachine.com\/blog\/wp-json\/wp\/v2\/pages\/15"}],"wp:attachment":[{"href":"http:\/\/www.icismachine.com\/blog\/wp-json\/wp\/v2\/media?parent=108"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}