Outage LED Light
Apr. 1st, 2021 09:24 amВчера доделал еще один OutageLight с простеньким 8-битным микропроцессором PIC12F510.
В корпусе из под старого трансформаторного блока питания.
Туда поместился Ni-MH AA аккумулятор, 4 светодиода, два осветительных 5mm
и два индикаторных заряда - зеленый и красный - 3mm, и кнопка.
Идея в том, что когда отрубается свет он автоматически включается,
а так же кнопкой можно выбирать режимы.
При восстановлении света он выключается и занимается зарядкой аккумулятора.
Поделка несерьезная, но много забавных познавательных электрических сюрпризов.
Под катом если кому интересно вид Си-программы для этого приборчика.
200 строк кода, 400 bytes Flash ROM (из 1К), 14 Bytes RAM включая стек (из 32). :)
4 MHz 8-bits CPU...
В корпусе из под старого трансформаторного блока питания.
Туда поместился Ni-MH AA аккумулятор, 4 светодиода, два осветительных 5mm
и два индикаторных заряда - зеленый и красный - 3mm, и кнопка.
Идея в том, что когда отрубается свет он автоматически включается,
а так же кнопкой можно выбирать режимы.
При восстановлении света он выключается и занимается зарядкой аккумулятора.
Поделка несерьезная, но много забавных познавательных электрических сюрпризов.
Под катом если кому интересно вид Си-программы для этого приборчика.
200 строк кода, 400 bytes Flash ROM (из 1К), 14 Bytes RAM включая стек (из 32). :)
4 MHz 8-bits CPU...
/*
* File: OutageLight.c
* Author:
*
* Created on March 29, 2021, 8:01 PM
*/
// PIC12F510 Configuration Bit Settings
// 'C' source line config statements
// CONFIG
#pragma config OSC = IntRC // Oscillator Select (INTOSC with 1.125 ms DRT)
#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config CP = OFF // Code Protect (Code protection off)
#pragma config MCLRE = OFF // Master Clear Enable bit (GP3/MCLR pin functions as GP3, MCLR internally tied to VDD)
#pragma config IOSCFS = OFF // Internal Oscillator Frequency Select bit (4 MHz INTOSC Speed)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include xc.h
#include pic12f510.h
//=============================================================================
static const char CopyRight[] = __FILE__ " (C)xxx@gmail.com " __DATE__;
typedef unsigned char byte;
#define BIT_LEDS 0b1u
#define BIT_BAT 0b100u
#define BIT_BUT 0b1000u
#define BIT_POWER 0b10000u
#define BIT_BOOST 0b100000u
#define PIN_LEDS GPIObits.GP0
#define PIN_BUT GPIObits.GP3
#define PIN_BAT GPIObits.GP2
#define PIN_BOOST GPIObits.GP5
#define PIN_POWER GPIObits.GP4
#define ADC_OFF 0b00101100u
#define ADC_BAT 0b01101011u
#define ADC_VREF 0b00101111u
#define ADC_SET( adc ) ADCON0 = adc;
#define ADC_WAIT while( ADCON0 & 2u );
#define COMP_OFF 0b11100001u
#define LED_GREEN 1u
#define LED_RED 0
#define ON 1u
#define OFF 0
const byte TRIS_BASE = BIT_BUT | BIT_POWER;
static bit bit_power, bit_light, bit_light_power,
bit_but, bit_but_click, bit_bat_full, bit_bat_charge;
static byte Timer;
// ------------------------------ CODE ----------------------------------
#define UPDATE_TIMER( tmr ) if(tmr) --tmr;
static void UpdateTimers(void)
{
static byte timer;
byte t = TMR0;
if(t < timer)
{
UPDATE_TIMER(Timer)
}
timer = t;
}
static void ADC(byte adc)
{
byte t = 8u;
do
{
ADC_SET(adc)
--t;
ADC_WAIT
}
while(t);
}
static void CheckPower(void)
{
if(PIN_POWER)
{
ADC(ADC_VREF);
bit_power = ADRES < 60u;
ADC_SET(ADC_OFF);
return;
}
bit_power = OFF;
}
static void CheckBattery(void)
{
ADC(ADC_VREF);
byte vref = ADRES; //0.6V
ADC(ADC_BAT);
bit_bat_full = ADRES >= (vref << 1) + (vref >> 1); // 1.5V
//bit_bat_full = OFF; // DEBUG
bit_bat_charge = ADRES <= (vref << 1) + (vref >> 2); // 1.35V
//bit_bat_charge = ON; // DEBUG
ADC_SET(ADC_OFF)
}
static void CheckButton(void)
{
if(PIN_BUT)
{
bit_but_click = bit_but;
bit_but = OFF;
return;
}
bit_but = ON;
bit_but_click = OFF;
}
void InitMCU()
{
OPTION = 0b11000111u;
TRIS = TRIS_BASE | BIT_BAT | BIT_LEDS;
GPIO = 0;
CM1CON0 = COMP_OFF;
ADCON0 = ADC_OFF;
}
static void ChargeOn(void)
{
PIN_LEDS = LED_RED;
PIN_BAT = ON;
TRIS = TRIS_BASE;
}
static void ChargeOff(void)
{
TRIS = TRIS_BASE | BIT_BAT | BIT_LEDS;
}
static void ChargeDone(void)
{
PIN_LEDS = LED_GREEN;
TRIS = TRIS_BASE | BIT_BAT;
}
static void BoostIdle(void)
{
for(;;)
{
ADC(ADC_VREF);
if(ADRES < 64u) // 2.4V
break;
PIN_BOOST = ON;
NOP();
NOP();
NOP();
NOP();
NOP();
NOP();
PIN_BOOST = OFF;
}
ADC_SET(ADC_OFF);
}
static void BoostLow(void)
{
byte p = 4u;
while(--p)
{
PIN_BOOST = ON;
NOP();
NOP();
NOP();
NOP();
NOP();
PIN_BOOST = OFF;
}
}
static void Boost(byte power)
{
byte i = 8u, p;
do
{
PIN_BOOST = ON;
p = power;
while(--p);
PIN_BOOST = OFF;
}
while(--i);
}
/*============================== main() ================================*/
void main(void)
{
InitMCU();
for(;;)
{
UpdateTimers();
if(bit_power)
{
if(Timer == 0)
{
CheckBattery();
if(bit_bat_full)
ChargeDone();
else
if(bit_bat_charge)
ChargeOn();
Timer = 255u;
}
CheckPower();
if(!bit_power)
{
ChargeOff();
bit_light = ON;
bit_light_power = ON;
}
}
else //if(bit_power)
{
CheckPower();
if(bit_power)
{
ChargeOn();
Timer = 48u;
bit_light = OFF;
bit_light_power = OFF;
}
}
CheckButton();
if(bit_but_click)
{
if(bit_light)
{
if(bit_light_power)
bit_light_power = OFF;
else
bit_light = OFF;
}
else
{
bit_light = ON;
bit_light_power = ON;
}
bit_but_click = 0; // click consumed
}
if(bit_light)
{
if(bit_light_power)
Boost(7u);
else
BoostLow();
}
else
BoostIdle();
}//for(;;)
}/*=========== main() ========*/