Страница 3 из 5
Re: Помогите ужать програаму, немного не влезает в ATTiny13
Добавлено: Пт окт 10, 2014 07:53:04
Gisteresis
Kavka писал(а):Сколько по памяти получилось?
Получился предел мечтаний. 397слов сейчас. (Для вас конечно нет, но я в начале просто хотел чтобы прога залезла в кристалл)
Частота обновления дисплея выставлена таймером, минимум чтобы глаз не замечал мерцания. Тут все в порядке.
А вот отсчет прыгает то на следующее значение, то на предыдущее. Причем очень часто. Условно так: 4579, 4586, 4586, 4579, 4586... и последние 2 декады замыливаются. Если предпоследнюю еще можно различить, то последнюю нет.
Конденсаторы стоят 100пик
Вообще схема почти вот такая:
http://piccy.info/view3/7056674/27fe185 ... de5b/1200/
Только без стабилизатора тока, и вольтметр сделан делителем, тоже с конденсатором.
Сейчас стоит просто потенциометр 10к, который делит 5В и подается прямо на ноги, минуя делитель и усилитель. Конденсаторы на ногах стоят.
ПС: Нннда... я удивлялся как математические операции делают на ПК, там например транспонимарование матриц при помощи SSE... тут походу покруче замес

Re: Помогите ужать програаму, немного не влезает в ATTiny13
Добавлено: Пт окт 10, 2014 08:10:32
vdavid
Gisteresis
100 пик - это конечно круто

. Поставьте лучше 100 нан. И R1 сильно уменьшить бы неплохо.
А под мельтишением я подразумевал именно слишком частую смену значений. Частота динамической индикации здесь ни при чем.
Re: Помогите ужать програаму, немного не влезает в ATTiny13
Добавлено: Пт окт 10, 2014 08:44:36
Gisteresis
vdavid писал(а):И R1 сильно уменьшить бы неплохо.
На днях прочитал про то, что сопротивление перед АЦП должно быть меньше 10к. 7.5к хватит?
Re: Помогите ужать програаму, немного не влезает в ATTiny13
Добавлено: Пт окт 10, 2014 08:50:16
Pink-Pank
Зависит от частоты выборок. Чем больше частота - тем меньше должно быть сопротивление, чтобы успевал зарядиться внутренний конденсатор АЦП (его емкость порядка 13-14 пФ + сопротивление открытого ключа АЦП при выборке ~1 кОм + сопротивление Вашего резистора). А там уже считайте по формуле 1/RC и берите с запасом.

Re: Помогите ужать програаму, немного не влезает в ATTiny13
Добавлено: Пт окт 10, 2014 09:11:11
Gisteresis
R=(1/FC)-1000
Частота выбрана минимальная 75кГц
(1/75000*14*10^-12)-1000 = 951381 Ом
Почти 1 мегом, верно ли я считаю?
Пикофарад это 1*10^-12 фарад.
Re: Помогите ужать програаму, немного не влезает в ATTiny13
Добавлено: Пт окт 10, 2014 09:28:32
shads
А как должна инфа отображаться на дисплее?
Если измерение тока и напряжения, то я так понимаю должно быть 2 четырех разрядных дисплея, на одном напруга на другом ток... но на схеме почему то один дисплей, хотя место есть для второго...
И значение должно быть с одним знаком после точки?
Re: Помогите ужать програаму, немного не влезает в ATTiny13
Добавлено: Пт окт 10, 2014 09:29:33
Pink-Pank
верно ли я считаю?
Не совсем. Выборка происходит в первый такт из 13 тактов преобразования.

Т.е. реальное максимальное значение резистора будет в 13 раз меньше, т.е. не более 73 кОм для данной частоты выборок, чтобы не было искажений сигнала. Но лучше брать раза в два меньше - с запасом.
Re: Помогите ужать програаму, немного не влезает в ATTiny13
Добавлено: Пт окт 10, 2014 10:39:59
vdavid
Pink-Pank писал(а):Зависит от частоты выборок.
Вообще-то зависит от того, что и как мы измеряем. Это же не осциллограф и для усреднения результата мы делаем 256 выборок. Конденсатор служит для тех же целей, поэтому 1/RC может быть того же порядка, что и период всех выборок для усреднения. Я бы ничего не считал, а поставил 10 (можно 7.5) кОм и 0.1 мкФ.
Да и тактов преобразования здесь вовсе не 13. Плюс зачем-то задержка в 10 мкс перед запуском нового преобразования.
Re: Помогите ужать програаму, немного не влезает в ATTiny13
Добавлено: Пт окт 10, 2014 11:04:26
Gisteresis
shads, извиняюсь за то что привел не совсем верную схему. Но я ниже пояснял что она доработана до вольтметра и амперметра, соответсвенно все как вы говорите 4 декады на вольты, 4 декады на амперы.
shads писал(а):И значение должно быть с одним знаком после точки?
Нее, так как я дисплей уже сделал, для вольт будет 2 знака после точки, а для ампер 3. Пофиг что там в конечных декадах будет шлак.
vdavid писал(а):Плюс зачем-то задержка в 10 мкс перед запуском нового преобразования.
Это генератор кода лепит и комментит что типа это стабилизирует результат преобразования...
По сути можно удалять.
Код: Выделить всё
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
Re: Помогите ужать програаму, немного не влезает в ATTiny13
Добавлено: Пт окт 10, 2014 11:10:06
Pink-Pank
Да и тактов преобразования здесь вовсе не 13..
Чтобы не ошибиться - проще отталкиваться от частоты тактирования АЦП. ) Тогда никакие такты считать не надо. и речь щла именно о максимальном номинале резистора. Если поставить слишком большой - конденсатор не будет успевать заряжаться/разряжаться - результат будет неверным.
Вообще, Атмеловцы рекомендуют в ДШ ставить резисторы не более 10 кОм, но они, видимо, отталкиваются от максимально возможной частоты тактирования АЦП + запас какой-то. Я в реальности ставил 200 кОм и понижал частоту примерно до 35 кГц - и все хорошо работало.
Re: Помогите ужать програаму, немного не влезает в ATTiny13
Добавлено: Пт окт 10, 2014 13:02:11
vdavid
Pink-Pank писал(а):
Чтобы не ошибиться - проще отталкиваться от частоты тактирования АЦП.
Так именно их родимых будет 13 только в режиме free running. Здесь же мы имеем ручной запуск, так что уже точно не менее 14.5, плюс время выполнения кода в прерывании плюс 10 мкс. Еще раз про тау RC. Поскольку мы измеряем только для визуализации, то обновлять информацию чаще 3 раз в секунду не следует точно. Посему логично измерять именно среднее значение между последовательными обновлениями. Исходя из этого конденсатор и в 1 мкф при 10 кОм не испортит картину.
Re: Помогите ужать програаму, немного не влезает в ATTiny13
Добавлено: Пт окт 10, 2014 18:23:51
Kavka
Gisteresis писал(а):Получился предел мечтаний. 397слов сейчас.
Это ФЛЭШ. А в ОЗУ сколько занято?
Re: Помогите ужать програаму, немного не влезает в ATTiny13
Добавлено: Пт окт 10, 2014 20:09:47
vdavid
Kavka, В последнем варианте с 32-х битной арифметикой

под стек осталось 47 байт. Хватит с головой.
Re: Помогите ужать програаму, немного не влезает в ATTiny13
Добавлено: Пт окт 10, 2014 20:47:41
Gisteresis
В общем все работает. Всем огромное спасибо.
Обнаружил ошибку в плате. Питание ОУ не разведено
Спойлер


Re: Помогите ужать програаму, немного не влезает в ATTiny13
Добавлено: Пт окт 10, 2014 20:57:33
vdavid
Gisteresis Так какой вариант прошивки, работает-то? Показания не сильно скачут? Мою последнюю пробовали?
Re: Помогите ужать програаму, немного не влезает в ATTiny13
Добавлено: Пт окт 10, 2014 21:36:20
Kavka
Во, уже всё закончилось
Я пару заходов сделал на причёсывание кода и не только.
Получилась пара вариантов под gcc. Может кому пригодиться. Сразу скажу, что особо не старался, ибо проверять не на чем. Соответственно, могут быть ошибки. Но компилируется.
Добавил на следующий день:
Думаю, что накапливать в сумму для усреднения будет лучше сами "сырые" значения АЦП и масштабировать их единожды...
Re: Помогите ужать програаму, немного не влезает в ATTiny13
Добавлено: Сб окт 11, 2014 11:56:38
Gisteresis
Не ну можно и до идеала довести
Работает вот такой
Спойлер
Код: Выделить всё
#include <tiny13a.h>
#include <delay.h>
// Declare your global variables here
inline void wr_reg(char cData)
{
char temp = cData;
char i=0;
for(i=0; i<8; i++)
{
PORTB.0 = (temp & 0x80);
#asm("nop");
PORTB.2 = 1;
#asm("nop");
PORTB.2 = 0;
temp = temp << 1;
}
}
inline void latch_reg()
{
#asm("nop");
PORTB.1 = 1;
#asm("nop");
PORTB.1 = 0;
}
flash char cSeg[]={
0b00111111, // 0
0b00000110, // 1
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101, // 6
0b00000111, // 7
0b01111111, // 8
0b01101111 // 9
};
char cDec = 0;
volatile char cDigit[8];
interrupt [TIM0_COMPA] void timer0_compa_isr(void)
{
wr_reg(1<<cDec);
wr_reg(cDigit[cDec]);
//wr_reg(0b00000000);
latch_reg();
cDec += 1;
if( cDec > 7 )
cDec = 0;
TCNT0 = 0;
}
void toDigits(unsigned char i, unsigned long* ulSum) {
unsigned char j;
j=4;
*ulSum=(5000UL*(*ulSum))/(256UL*1024);
while (j>0) {
j--;
cDigit[i+j] = ~cSeg[*ulSum%10];
*ulSum /=10;
}
*ulSum = 0;
}
#define FIRST_ADC_INPUT 2
#define LAST_ADC_INPUT 3
#define ADC_VREF_TYPE 0x00
unsigned long ulVoltsSum = 0;
char sCounterVSum = 0;
unsigned long ulAmpersSum = 0;
char sCounterASum = 0;
// ADC interrupt service routine
// with auto input scanning
interrupt [ADC_INT] void adc_isr(void)
{
static unsigned char input_index=0;
// Read the AD conversion result
//// Select next ADC input
if (++input_index > LAST_ADC_INPUT)
input_index=FIRST_ADC_INPUT;
ADMUX=ADC_VREF_TYPE +input_index;
if( input_index == 2 )
{
ulVoltsSum += ADCW;
sCounterVSum++;
if( !sCounterVSum )
{
toDigits(0,&ulVoltsSum);
cDigit[1] &= ~0b10000000;
sCounterVSum = 0;
}
}
if( input_index == 3 )
{
ulAmpersSum += ADCW;
sCounterASum++;
if( !sCounterASum )
{
toDigits(4,&ulAmpersSum);
cDigit[4] &= ~0b10000000;
sCounterASum = 0;
}
}
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
}
void main(void)
{
// Declare your local variables here
// Crystal Oscillator division factor: 1
/*#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif*/
// Input/Output Ports initialization
// Port B initialization
// Func5=In Func4=In Func3=In Func2=In Func1=In Func0=Out
// State5=T State4=T State3=T State2=T State1=T State0=0
//PORTB=0x00;
DDRB=0x07;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 9400,000 kHz
// Mode: Normal top=0xFF
// OC0A output: Clear on compare match
// OC0B output: Disconnected
//TCCR0A=0x00;
TCCR0B=0x05;
//TCNT0=0x00;
OCR0A=0x10;
//OCR0B=0x00;
// External Interrupt(s) initialization
// INT0: Off
// Interrupt on any change on pins PCINT0-5: Off
//GIMSK=0x00;
//MCUCR=0x00;
// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x04;
// Analog Comparator initialization
// Analog Comparator: Off
ACSR=0x80;
//ADCSRB=0x00;
//DIDR0=0x00;
// ADC initialization
// ADC Clock frequency: 73,438 kHz
// ADC Bandgap Voltage Reference: Off
// ADC Auto Trigger Source: ADC Stopped
// Digital input buffers on ADC0: Off, ADC1: Off, ADC2: On, ADC3: On
DIDR0&=0x03;
DIDR0|=0x24;
ADMUX=FIRST_ADC_INPUT | (ADC_VREF_TYPE & 0xff);
ADCSRA=0xCF;
#asm("sei")
while(1)
{
}
}
Отличия:
Изменил ноги вывода в регистры под свою плату.
Добавил десятичные точки
Сделал быстрее таймер. Дисплей мерцал. Старое значение таймера было выбрано для 4х1 дисплея.
Ну и усреднения 256 отстчетов. Значения меняются примерно 3..4 раза в секунду если дергается. Но в основном это только последний разряд, остальные разряды вполне комфортно читабельны.
Регулировка пока не понял. Но похоже немного нелинейна. Настраиваю на максимальном значении (29В и ток по потенциометру который делит 5В до 0.5В имитируя шунт 0.1Ом) Точно сказать немогу, но пока такое ощущение что в пределах 100мВ погрешность. Прецизионным конечно не назовешь, но в блок питания пойдет. Учитывая что разрешение в 10бит, реально 8, больше и недадут. Ток тоже скурпулезно не мерял, но тоже уплывает порядка 100..200мА. Так как стоит ОУ lm358 меряет не от нуля. И еще небыло отдельного питания для ОУ, подключил его к 5В, выход упирался в 3.6В (тоесть ток показывал 3600мА на дисплее).
Выходной резистор так и не сменил пока, он так 100к и стоял, и все похоже работает. Конденсаторы тоже пока 100пик. В ближайщее время поменяю на рекомендованные вами.
Общие впечатления от поделки хорошие. С продающимися встраиваемыми цифровыми вольтметрами и амперметрами не сравнивал.
Подозреваю в оставшееся место памяти даже влезет и ваттметр или небольшая программа регулятора... Мне нужен был АмперВольтМетр я им ограничиваюсь.
Неудобство использования в том что ОУ требует питания больше 5В. В связи с этим нужно или на самой плате размещать 5ти вольтовый стабилизатор или еще как.
Кто как делает? Обязательно нужен собственный стабилизатор?
Как вы советуете к питанию прикрутить дроссель для фильтрации? Все схемы которые нахожу для более жирных МК, у которых есть Aref. Насколько это вообще актуально?
Kavka, ваш код попозже посмотрю. Может что скрестить можно.
Re: Помогите ужать програаму, немного не влезает в ATTiny13
Добавлено: Сб окт 11, 2014 19:16:36
Kavka
В общем то же самое.
Пару моментов.
Вот это
заменяется на вот это
Мелочь, но избавляет от ветвления.
И об усреднении отсчётов АЦП.
1023 * 256 = 261888 в unsigned int не влезает, то есть 32 битное целое. Как есть.
26188 * 5000 = 1309440000 тоже 32 битное целое. Как есть.
26188 * 5000 / (256 * 1024) = 5000 прекрасно умещается в unsigned int
Таким образом вот тут
Код: Выделить всё
// unsigned long* ulSum
*ulSum=(5000UL*(*ulSum))/(256UL*1024);
результат вычисления выражения можно сохранить в переменной меньшей длинны. Что далее уменьшит сложность вычисления модуля и деления.
Re: Помогите ужать програаму, немного не влезает в ATTiny13
Добавлено: Сб окт 11, 2014 19:20:09
vdavid
Kavka писал(а):
результат вычисления выражения можно сохранить в переменной меньшей длинны. Что далее уменьшит сложность вычисления модуля и деления.
Ага, только увеличится как использование флеша, так и оперативки

.
Re: Помогите ужать програаму, немного не влезает в ATTiny13
Добавлено: Сб окт 11, 2014 20:31:13
Mishany
с вычислениями сталкивался с проблемой невлазания в int, использование uint_32 заметно загружает мк вычислениями, и еще заметил одну особенность в вычислениях если в процессе вычислений (все переменные int) по формуле два множителя дают >65535 то результат вычислений получается неправильный. толи у меня глюки были толи я чего не понимаю. в итоге считал отдельно тысячи и отдельно сотни x/1000 и x%1000