Внедорожный портал клуба «Скиф 4х4»
Одного из крупнейших клубов Юга России
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Список форумов » Сообщения от Савелий
silver_dog, фоты давай) я только домой попал, у мну бенз кончился по дороге домой.. было больше всех его, надо карб перебирать.
Вывод - номер карты без повода палить не надо. Можно пользовать хотя бы тот же PayPal
qiwi virtual? никаких овердрафтов
1) нашел ошибки, даже не успев дособирать. Детали со старой платы десантировал, новую исправленную сделал, пока не распаял.
2) По поводу алгоритма включения/выключения - добавил условие. Если есть импульсы на тахометр - прибор не выключается. Выключается через N секунд только если
-а) напряжение питания ниже 13 вольт
-б) нет сигнала на тахометр.
Интересующимся покажу программу, думаю окончательный вариант (только настройки поменять, для теста уменьшал например время выключения и т.д.)
Правда, еще нет функций калибровки. Надо привязываться на ноль амперметру и на стабилизированные 5в вольтметру.
#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
/* пины */
#define SH_CP PB0 //защелка регистра
#define ST_CP PB1 //clock регистра
#define DATA PB2 //данные в регистр
#define LED_BRI PB4 //яркость подсветки (программный шим)
#define BUT_MODE PB3 //кнопка выбора режима
#define BUT_BRI PB5 //кнопка выбора яркости
#define RED_LED PA3 //красный светодиод галактека опасносте
#define EX_LED PA0 //вход сигнала габаритов
/* настройки */
#define TAXO_DIV 4 //количество импульсов за оборот коленвала
#define TAXOLED_DIV 200 //оборотов на один светодиод
#define AMP_DIV 2 //делитель (коэффициент) амперметра. На него делится значение +-512
#define VOLTMETER_DIV 25 //резисторный делитель * опорное напряжение (5в) и еще что то
#define OFF_TIME 3000 //время выключения при бортовом ниже OFF_VOLT
#define OFF_VOLT 130 //порог, ниже которого устройство отрубается через OFF_TIME
/* вспомогательное */
//настройки
/* переменные */
volatile unsigned char mode=0; //0 - вольтметр, 1 - амперметр, 2 - тахометр
volatile unsigned char mode_off=0; //0 - дисплей выкл, 1 - дисплей вкл
volatile unsigned long millis; //счетчик прошедших миллисекунд с начала работы
volatile unsigned long prev_millis_main; //храним время последнего вызова главного цикла
volatile unsigned long prev_millis_off; //храним время отключения если низкое бортовое
volatile unsigned char taxo_tmp; //временная переменная тахометра, используемая в прерывании
volatile unsigned int taxo; //переменная тахометра
volatile signed int amp; //переменная амперметра
volatile unsigned char amp_sign; //знак амперметра
volatile unsigned int volt; //переменная напряжения
volatile unsigned char to_display[4]; //цифры и символы для вывода на дисплей
volatile unsigned char digit_step; //шаг вывода на дисплей/текущая цифра
volatile unsigned char bri[2]; //яркость дисплея и светодиодов линейки тахометра
volatile unsigned char bri_step; //шаг цикла яркости
//цифры ==>dp gfedcba
static unsigned char symbols[14] = {
0b00111111, //0 [0]
0b00000110, //1 [1]
0b01011011, //2 [2]
0b01001111, //3 [3]
0b01100110, //4 [4]
0b01101101, //5 [5]
0b01111101, //6 [6]
0b00000111, //7 [7]
0b01111111, //8 [8]
0b01101111, //9 [9]
0b00000000, //sp[10]
0b01110111, //A [11]
0b00111110, //U [12]
0b01000000 //- [13]
};
/* вспомогательные функции */
//пауза
void pause(unsigned int _pause){
unsigned int i;
for (i = _pause * 1000; i>0; i--) asm("nop");
}
//ADC function - оцифровка
unsigned int ADC_input(unsigned char _pin) {
//выбор пина
if (_pin == 1) ADMUX = (1 << MUX0); //ADC1
if (_pin == 2) ADMUX = (1 << MUX1); //ADC2
ADCSRA |= (1 << ADEN);
ADCSRA |= (1 << ADSC); // Включаем оцифровку
while (ADCSRA & (1 << ADSC)); //Ждем окончания
ADCSRA &= ~(1<<ADEN); // остановим оцифровку
return (ADCL|ADCH<<8); //отдаем результат
}
//заносит цифры и символы в массив to_display
void to_numbers(unsigned int _number) {
to_display[0] = 0;
to_display[1] = 0;
to_display[2] = 0;
to_display[3] = 0;
//разбираем число на символы
while (_number >= 1000) {
_number -= 1000;
to_display[0]++;
}
while (_number >= 100) {
_number -= 100;
to_display[1]++;
}
while (_number >= 10) {
_number -= 10;
to_display[2]++;
}
to_display[3] = _number;
if(mode == 0) to_display[0] = 12; //если режим вольтметра выводим U
if(mode == 1 && amp_sign == 1) to_display[0] = 13; //если режим амперметра и разряд выводим минус
else if(mode == 1) to_display[0] = 11; //если режим амперметра выводим А
if((mode==0 || mode ==1 ) && to_display[1]==0) to_display[1] = 10; //если режим амер/вольтметра и первый ноль, ставим взамен пробел
}
//формирование потока на регистр из одного байта
void shiftout(char _byte){
//цикл по битам
for (char i=0; i<=7; i++) {
if(_byte&(1<<i)) PORTB |= (1<<DATA);
else PORTB &= ~(1<<DATA);
//обозначим clock
PORTB |= (1<<SH_CP);
PORTB &= ~(1<<SH_CP);
}
}
//вывод данных в регистры
void out(void) {
PORTA |= ((1<<PA4)|(1<<PA5)|(1<<PA6)|(1<<PA7)); //выключим катоды дисплея
PORTB &= ~(1<<LED_BRI); //выключим катод светодиодов
if(mode_off==1) {
PORTB &= ~(1<<ST_CP); //снимем "защелку" 74HC595
//отсылаем в три регистра состояние светодиодной линейки
for (char i=1; i<=24; i++) {
if((taxo/TAXOLED_DIV) >= i) PORTB |= (1<<DATA);
else PORTB &= ~(1<<DATA);
//обозначим clock
PORTB |= (1<<SH_CP);
PORTB &= ~(1<<SH_CP);
}
//отсылаем в регистр дисплея состояние
if((mode == 0 || mode == 1) && digit_step == 2) shiftout(symbols[to_display[digit_step]] | (1<<7)); //если вольтметр или амперметр ставим точку на втором разряде
else shiftout(symbols[to_display[digit_step]]); //иначе просто отсылаем
PORTB |= (1<<ST_CP); //установим "защелку" 74HC595
//цикл яркости, управляем катодами
if((PINA&(1<<EX_LED)&&bri_step <= bri[0]) || (!(PINA&(1<<EX_LED))&&bri_step <= bri[1])) { //если установленная яркость разрешает вывод (с учетом сигнала габаритов)
//катоды дисплея
PORTA &= ~(1<<(digit_step+4)); //включим нужный катод
//яркость светодиодов
PORTB |= (1<<LED_BRI); //включим катод светодиодов
}
//изменение шагов
digit_step++;
if(digit_step == 4) {
digit_step = 0;
bri_step++;
if(bri_step == 9) bri_step = 0;
}
}//mode_off
}
//обработчик таймера
ISR (TIMER1_COMPA_vect) {
millis++; //счетчик миллисекунд
out(); //обновим дисплей
}
//обработчик прерывания (импульсы с тахометра)
ISR (INT0_vect) {
taxo_tmp++;
}
/* Главное тело программы */
int main(void) {
//настройки пинов
DDRA = 0b11111000; //катоды дисплея, аварийный светодиод
PORTA = 0b00000001; //подтягивающий резистор входа габаритов
DDRB = 0b00010111; //управление регистрами, управление яркостью
PORTB = 0b01101000; //подтягивающие резисторы кнопок, тахометра (прерывание)
//прерывания
MCUCR = (1<<ISC01) | (1<<ISC00); //rising of int0
GIMSK = (1<<INT0); //тахометр на INT0 (PB6)
//настройка таймера
OCR1C = 125; // основной счетчик
//OCR1A = 200; //значение совпадения (скважность)
//TCCR1A = (2 << COM1A0) | (1 << PWM1A); //FastPwm PB1
TCCR1A = (1 << PWM1A); //FastPwm
//TCNT1 = 0;
PLLCSR = (1 << PLLE);
while (!(PLLCSR & (1 << PLOCK)));
PLLCSR = (1 << PLLE);
TCCR1B = (1 << CS10) | (1 << CS11) | (1 << CS12); //=8000000/64/125(OCR1C) = 1000hz
TIMSK = (1<<OCIE1A); //вызов функции по прерыванию
asm("sei"); //разрешить прерывания
//частота АЦП
ADCSRA = (1 << ADPS2)|(1 << ADPS1)|(1 << ADPS0); // Делитель clock / 128
//зададим на дисплее "минусы" при включении
mode = 9; //костыль против точки на 2-и сегменте
for(int x=0; x<=3; x++)
to_display[x]=13;
//тест линеек - вверх
for (int x=1; x <= 24; x++) {
taxo = x * TAXOLED_DIV;
pause(5+x);
}
//вниз
for (int x=23; x >= 1; x--) {
taxo = x * TAXOLED_DIV;
pause(x);
}
//читаем настройки из eeprom
do {} while (!eeprom_is_ready());
mode = eeprom_read_byte((unsigned char*)0x00);
do {} while (!eeprom_is_ready());
bri[0] = eeprom_read_byte((unsigned char*)0x01); //яркость без габаритов
bri[1] = eeprom_read_byte((unsigned char*)0x02); //яркость с габаритами
if(bri[0] < 2 || bri[0] > 8) bri[0] = 8; //если яркость за пределами, ставим максимальную
if(bri[1] < 2 || bri[1] > 8) bri[1] = 8;
/* главный цикл */
while(1){
//время рассчитать значения, опросить кнопки
if(millis >= (prev_millis_main + 200)) {
prev_millis_main = millis; //выравниваем счетчики времени
//расчет тахометра
taxo = ((taxo_tmp * 5 * 60) / TAXO_DIV); //рассчитываем с учетом количества импульсов за оборот коленвала, приводим к об/сек, далее к об/мин
taxo_tmp = 0; //сбрасываем временный счетчик
//расчет амперметра
amp = ADC_input(1); //0..1023
if (amp < 511) {
amp_sign = 1;
amp = (511 - amp) / AMP_DIV;
}
else {
amp_sign = 0;
amp = (amp - 512) / AMP_DIV;
}
//расчет вольтметра
volt = VOLTMETER_DIV * ADC_input(2) / 102; //Расчитываем по делителю
//опрашиваем кнопки
if(!(PINB&(1<<BUT_MODE))){ //BUT_MODE
while(!(PINB&(1<<BUT_MODE))) pause(1);
//перебор режима
prev_millis_off = millis;
if(mode_off==1){ //если дисплей включен
mode++;
if(mode >= 3) mode = 0;
do {} while (!eeprom_is_ready());
eeprom_write_byte((unsigned char*)0x00, mode);
} //mode off
}
if(!(PINB&(1<<BUT_BRI))){ //BUT_BRI (2..4..6..8)
while(!(PINB&(1<<BUT_BRI))) pause(1);
//перебор режима
prev_millis_off = millis;
if(mode_off==1){ //если дисплей включен
if(PINA&(1<<EX_LED)) { //сигнала габаритов нет
bri[0] += 2;
if(bri[0] > 8) bri[0] = 2;
do {} while (!eeprom_is_ready());
eeprom_write_byte((unsigned char*)0x01, bri[0]);
}
else {
bri[1] += 2;
if(bri[1] > 8) bri[1] = 2;
do {} while (!eeprom_is_ready());
eeprom_write_byte((unsigned char*)0x02, bri[1]);
}
} //mode off
}
//выбор отображения по режиму
if(mode == 0) to_numbers(volt); //режим амперметра
if(mode == 1) to_numbers(amp); //режим вольтметра
if(mode == 2) to_numbers(taxo); //режим тахометра
//if(mode == 3) to_numbers(bri[0]); //режим отладки
//if(mode == 4) to_numbers(bri[1]); //режим отладки
if(volt < OFF_VOLT && taxo == 0 && millis > prev_millis_off + OFF_TIME) mode_off=0; //если таймаут и низкое бортовое (двиг не заведен) - выключить дисплей
else { //иначе
if(mode_off == 0) prev_millis_off = millis; //если первый цикл после включения - уравняем время
mode_off=1; //включим дисплей
}
//RED_LED - аварийный светодиод
if(taxo > 4000 || volt <= 115 || amp_sign == 1) PORTA |= (1<<RED_LED);
else PORTA &= ~(1<<RED_LED);
}//расчеты, опрос кнопок
} //главный цикл
}Подниму тему. Шлагбаумов нет? Все проезжабельно? Трек дадите? )
Hi Com, перенесем на "после"..
нету денег.. ну нету! (
ЗЫ за бумажкой то налогом куда подъехать если завтра под вечер?
igor4737, электрические?

MOHCTPOXOD, хотелось обойтись только двумя проводами на амперметр. На шунт.
45ватт... мечта
MOHCTPOXOD, цель - минимум проводов. Если питать прибор, измерять вольты и амперы можно по трем проводам - отчего нет? отдельно желающим прошью без автоматики и от зажигания пусть запитывают
озик на асфальте глючит страшенно, включайте навител..
Волк, смысла особо нет.. там 99% вес - карты
igor4737, тебе отключим автоматику, тебе нельзя
Волк, Озик и часть карт влезут, не влезут 250-метровки. генштаб весь влезет.
Lesnik93rus, незачто.. к четвертому ориентируйся, крайне желательно днем в городе пересечься забрать..
Lesnik93rus, зависит от магнитолы, от наличия в ней видеовыхода. Ну думаю он есть.
Видеовход, если верить интернетам, в навигаторе есть. Нужен шнурок/переходник с тюльпанов на 3,5mm jack 4-pin (видео для навигатора) на радиорынке.
Lesnik93rus, да
---
флешки не забудьте, 8 или 16 гб 6-10 класс
У кого можно взять на выходные оссицилограф, желательно максимально переносной? Возможно, есть вариант считать тахометр вообще без подключения куда либо..
igor4737, я в курсе.. там чуть сложнее чем обычно.
igor4737, хороший аккум 12 выдаст..
тут нюанс при реализации автовключения-отключения.. При низком бортовом прибор 30сек будет сигнализировать что непорядок, потом тупо уснет.. Оно надо?
Ququbrick, лучше заглянуть в подшипники пораньше.
Поменяю на вменяемый бак под задним сиденьем 175л от ЗИЛа (в багажнике уаза). промыть можно, хотя стоит/работает/ездит. Горловина заварена, выведена трубка вверх/вбок 50мм. Даже датчик стыкуется с уазом )
shaman, доработал. Спит через 30 сек, если бортовое ниже 13. Любая кнопка "просыпает" еще на 30 сек.
Вживую собрать опять руки не дошли...
Список форумов » Сообщения от Савелий
© Внедорожный клуб «Скиф 4х4», 2005—2022