hi zusammen,
ich sitze grade an einer neuen Firmware für die üblichen Nangj 105C Treiber.
Als Basis zur Spannungserkennung habe ich die Battcheck-Firmware von Toykeeper genutzt, und zur Modiweiterschaltung den Minimo von DrJones.
http://bazaar.launchpad.net/~toykeeper/flashlight-firmware/trunk/files/178/ToyKeeper/battcheck
die liefert mir je nach Spannung einen Wert zwischen 0 und 254. Mit Messungen kann ich diese Werte dann den entsprechenden Spannungen zuordnen. soweit kein Problem.
ich habe dann zum Testen einfach mal nach der Modiwahl per Taster eingefügt:
Habe den Treiber damit geflashed und am Netzteil betrieben.
Mein Problem: Wenn ich in der hellsten Stufe bin und ich drehe die Spannung runter, geht die LED ab 3,6V aus. Wenn ich in der dunkleren Stufe bin, geht die LED ab 3,2V aus.
Warum sind die Abschaltspannungen denn Modiabhängig ? Der Treiber hängt am Netzteil, das kann die Spannung konstant halten, egal welcher Strom fließt ?
Bin ein wenig ratlos, das gleiche Problem hatte ich schonmal bei einem früheren Projekt, habe dann die Akkustandsanzeige dann nur im Standby aktiviert.
Bin für jeden Ratschlag dankbar.
Lg Michael
ich sitze grade an einer neuen Firmware für die üblichen Nangj 105C Treiber.
Als Basis zur Spannungserkennung habe ich die Battcheck-Firmware von Toykeeper genutzt, und zur Modiweiterschaltung den Minimo von DrJones.
http://bazaar.launchpad.net/~toykeeper/flashlight-firmware/trunk/files/178/ToyKeeper/battcheck
Code:
/*
* This firmware simply helps calibrate values for voltage readings.
* It is not intended to be used as an actual flashlight.
*
* It will read the voltage, then read out the raw value as a series of
* blinks. It will provide up to three groups of blinks, representing the
* hundreds digit, the tens digit, then the ones. So, for a raw value of 183,
* it would blink once, pause, blink eight times, pause, then blink three times.
* It will then wait longer and re-read the voltage, then repeat.
*
* NANJG 105C Diagram
* ---
* -| |- VCC
* Star 4 -| |- Voltage ADC
* Star 3 -| |- PWM
* GND -| |- Star 2
* ---
*
* CPU speed is 4.8Mhz without the 8x divider when low fuse is 0x75
*
* define F_CPU 4800000 CPU: 4.8MHz PWM: 9.4kHz ####### use low fuse: 0x75 #######
* /8 PWM: 1.176kHz ####### use low fuse: 0x65 #######
* define F_CPU 9600000 CPU: 9.6MHz PWM: 19kHz ####### use low fuse: 0x7a #######
* /8 PWM: 2.4kHz ####### use low fuse: 0x6a #######
*
* Above PWM speeds are for phase-correct PWM. This program uses Fast-PWM,
* which when the CPU is 4.8MHz will be 18.75 kHz
*
* FUSES
* I use these fuse settings
* Low: 0x75
* High: 0xff
*
* STARS (not used)
*
*/
// set some hardware-specific values...
// (while configuring this firmware, skip this section)
#define F_CPU 4800000UL
#define EEPLEN 64
#define DELAY_TWEAK 950
#include <avr/io.h>
#include <util/delay.h>
/*
* =========================================================================
* Settings to modify per driver
*/
#define OWN_DELAY // Should we use the built-in delay or our own?
#define BLINK_PWM 10
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <avr/eeprom.h>
#include <avr/sleep.h>
#define STAR2_PIN PB0
#define STAR3_PIN PB4
#define STAR4_PIN PB3
#define PWM_PIN PB1
#define VOLTAGE_PIN PB2
#define ADC_CHANNEL 0x01 // MUX 01 corresponds with PB2
#define ADC_DIDR ADC1D // Digital input disable bit corresponding with PB2
#define ADC_PRSCL 0x06 // clk/64
#define PWM_LVL OCR0B // OCR0B is the output compare register for PB1
inline void ADC_on() {
ADMUX = (1 << REFS0) | (1 << ADLAR) | ADC_CHANNEL; // 1.1v reference, left-adjust, ADC1/PB2
DIDR0 |= (1 << ADC_DIDR); // disable digital input on ADC pin to reduce power consumption
ADCSRA = (1 << ADEN ) | (1 << ADSC ) | ADC_PRSCL; // enable, start, prescale
}
inline void ADC_off() {
ADCSRA &= ~(1<<7); //ADC off
}
uint8_t get_voltage() {
// Start conversion
ADCSRA |= (1 << ADSC);
// Wait for completion
while (ADCSRA & (1 << ADSC));
// See if voltage is lower than what we were looking for
return ADCH;
}
void noblink() {
PWM_LVL = (BLINK_PWM>>2);
_delay_ms(5);
PWM_LVL = 0;
_delay_ms(200);
}
void blink() {
PWM_LVL = BLINK_PWM;
_delay_ms(100);
PWM_LVL = 0;
_delay_ms(200);
}
uint8_t modes[]={0,15,255}; //PWM values, 5..255 - LEAVE THE "0" THERE
int main(void)
{
// Set PWM pin to output
DDRB=2; PORTB=8; //define PB1 as output and pull-up switch on PB3
// Set timer to do PWM for correct output pin and set prescaler timing
TCCR0A = 0x21; // phase corrected PWM is 0x21 for PB1, fast-PWM is 0x23
TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...)
// Turn features on or off as needed
ADC_on();
ACSR |= (1<<7); //AC off
uint16_t voltage;
uint8_t i;
uint8_t count=0,mode=0,lastmode=1,waspressed=0; //define some variables used below
voltage = get_voltage();
while(1) {
// get an average of several readings
voltage = 0;
for (i=0; i<8; i++) {
voltage += get_voltage();
_delay_ms(3);
}
voltage = voltage/8;
if ((PINB&8)==0) { //when the button is pressed (PB3 pulled down)
count++; //count length of button press
if (count==16) { //pressed long (8*50ms)
if (mode>0) {lastmode=1; mode=0;} //was on? -> off, but remember the mode
else mode=lastmode; //was off? -> on, with previous mode.
}
waspressed=1; //remember that the button was pressed, see below
}
else { //button not pressed
if (waspressed) { //but it was pressed, so it has just been released!
waspressed=0; //reset that
if (count<16 && mode>0) { //really was a short press AND the light is on
mode++; if (mode>=sizeof(modes)) mode=1; //next mode
}
count=0; //reset counter
}
}
OCR0B=modes[mode]; //set PWM level (0 is off)
if(voltage <=150){
if (mode > 0){
OCR0B=0;
}
}
else{
OCR0B=modes[mode]; //set PWM level (0 is off)
}
_delay_ms(1); //wait a bit before checking again, important for counting
}
}
die liefert mir je nach Spannung einen Wert zwischen 0 und 254. Mit Messungen kann ich diese Werte dann den entsprechenden Spannungen zuordnen. soweit kein Problem.
ich habe dann zum Testen einfach mal nach der Modiwahl per Taster eingefügt:
Code:
if(voltage <=150){
if (mode > 0){
OCR0B=0;
}
}
Habe den Treiber damit geflashed und am Netzteil betrieben.
Mein Problem: Wenn ich in der hellsten Stufe bin und ich drehe die Spannung runter, geht die LED ab 3,6V aus. Wenn ich in der dunkleren Stufe bin, geht die LED ab 3,2V aus.
Warum sind die Abschaltspannungen denn Modiabhängig ? Der Treiber hängt am Netzteil, das kann die Spannung konstant halten, egal welcher Strom fließt ?
Bin ein wenig ratlos, das gleiche Problem hatte ich schonmal bei einem früheren Projekt, habe dann die Akkustandsanzeige dann nur im Standby aktiviert.
Bin für jeden Ratschlag dankbar.
Lg Michael