Технический форум по робототехнике.
thor_nsk » 12 ноя 2016, 20:21
Тема, смотрю, почти мертвая, но все же спрошу. Имею проблемы с ADC на Tiny85, а точнее не могу заставить работать. ADC проходит только раз при включении (либо это "помехи" включения МК) и все, больше значения не меняются. Игрался с делителем ADC, ручным и автозапуском ничего не получилось. Код на С прилагаю. Если кому не трудно, гляньте пожалуйста. Коротко о программе. Надо включить питание сенсора, провести АЦП, сверить полученные данные с эталоном и если все "плохо", то включить помпу на полив цветов. Затем уснуть на 24часа. Проснуться и повторить программу сначала. Все получается кроме "провести АЦП". Что я делаю не так?
- Вложения
-
- polivalka.c
- (5.44 КиБ) Скачиваний: 449
Madf » 12 ноя 2016, 20:26
Если используйте "Powerdown", то после просыпания, нужно около 50мс подождать, когда всё проснётся.
thor_nsk » 13 ноя 2016, 09:59
Я тоже поначалу грешил на энергосбережение и на функции пробуждения, думал не все включается. Поэтому для пробы сделал отдельный проект, просто АЦП в цикле. Еще была проблема мониторинга числа получаемого после АЦП. Единственный быстрый вариант смог сделать на светодиодной матрице с max 7219. Я на нее в двоичном коде выводил старший и младший байт результата АЦП. Та же песня, после подачи питания что-то появляется в регистре АЦП и потом не меняется. Либо не стартует начало преобразования, либо не срабатывает прерывание по окончанию АЦП. Код прилагаю. Я уже не знаю куда копать. Вроде все должно работать, а нифига не получается. Видимо есть какой-то нюанс который мне не известен. Помогите, пожалуйста, разобраться.
- Вложения
-
- tiny85.c
- (4.73 КиБ) Скачиваний: 482
Madf » 13 ноя 2016, 16:12
thor_nsk писал(а):Поэтому для пробы сделал отдельный проект, просто АЦП в цикле.
И? Работает?
thor_nsk писал(а):после подачи питания что-то появляется в регистре АЦП и потом не меняется
Есть известный баг АВР, АЦП после первого использования (включения) выдает мусор - это просто надо учитывать (первое измерение холостое и/или использовать накопления измерения (точно не однократное снятие значения).
thor_nsk писал(а):Код прилагаю.
Честно, я на Си не пишу (Bascom), помочь конекртно в этом не могу, только в общей идеологии. С прямой адресацией АЦП по регистрам работал (в асме), там ничего сложного, если что-то не работает - значит: просто после просыпания, нужно обязательно заного конфигурировать весь МК (по крайней мере, я так и делал), т.к. всё равно, перед спячкой, для правильного сна/потребления, нужно МК весь переводить в "девственное состояние" (выключать все таймера, порты все на вход настраивать, отключать пулапы), ну и выводить его соответсвующи...
Вот пример куска кода как я это делал (как раз для тини85):
- Код: Выделить всё • Развернуть
Disable Timer0
Config Pwr_mp3 = Input
Config Tx = Input
Enable Int0
Waitms 50
Powerdown 'Idle/Powerdown
Disable Int0
Waitms 50
Config Tx = Output
Config Pwr_mp3 = Output
Reset Pwr_mp3 ' включения блока мп3
Temp_word = Getadc(1)
Temp_word = 0
Enable Timer0
Здесь при включении, сразу делаю тестовый замер с АЦП, чтобы баг игнорить.
Вся схема настроена так, чтобы просыпаться по INT0 (через него же производится работа/измерение АЦП).
thor_nsk » 14 ноя 2016, 12:04
Madf писал(а):thor_nsk писал(а):Поэтому для пробы сделал отдельный проект, просто АЦП в цикле.
И? Работает?
В том-то и дело что не работает. В общих чертах что делаю:
1) ногу, с которой буду оцифровывать конфигурирую как вход;
2) выставляю делитель ЦАП, выбираю нужный вход, преобразование по команде, разрешаю прерывание по окончании ЦАП, включаю ЦАП
3) разрешаю прерывания
4) даю команду на старт ЦАП
И пункт 4 выполняю бесконечно, но кроме мусора, после старта МК, ничего не получаю.
На неделе попробую на меге16 поиграть с ЦАП. Может получится. Но хочется чтобы заработало на тиньке.
Просто сделал поливалку на ардуине нано, но решил что это жирно слишком. На тиньке получилось компактнее, но вот из-за проблем со стартом ЦАП пришлось использовать внешний датчик влажности с цифровым выходом. Но хочу домучить ЦАП
Madf » 14 ноя 2016, 14:05
Не ЦАП, а АЦП (Аналог в Цифру, не на оборот).
Если у вас не получается работать с АЦП через прерывание, то попробуйте обычные режимы (
ручном или непрерывном), зачем вам лишний геморрой с обработкой событий, пусть оно само молотит.
Dr.Unk » 01 дек 2016, 02:10
Приветствую.Подскажите пожалуйста, целый день пытаюсь разобраться с кодом. Задача: джойстик передает через UART данные вида (положение по осьХ, осьУ, кнопки).
На принимающей части пакет данных обрабатывается функцией sscanf(buffer, "%[^','],%[^','],%s", &strX, &strY, &key); . Кнопки отлично обрабатываются, а вот с осями проблема, .toInt() выдает некорректные результаты. Сервы не вращаются.
- Код: Выделить всё • Развернуть
Передатчик
int X = analogRead(axisX);
int Y = analogRead(axisY);
Serial.print(X);
Serial.print(",");
Serial.print(Y);
Serial.print(",");
Serial.println(key);
//Serial.println('\n');
- Код: Выделить всё • Развернуть
Приемник
Servo servX;
Servo servY;
int servXPoz = 90;
int servYPoz = 0;
int valX;
int valY;
char key ;
String strX;
String strY;
void loop() {
int i=0;
char buffer[12];
if(Serial.available()){
delay(50);
while( Serial.available() && i< 12) {
buffer[i++] = Serial.read();
}
buffer[i++]='\n';
}
if(i>0){
sscanf(buffer, "%[^','],%[^','],%s", &strX, &strY, &key);
}
valX = strX.toInt();
//valX = atoi(strX);
servXPoz = map(valX, 0, 1023, 0, 180);
servX.write(servXPoz);
valY = strY.toInt();
servYPoz = map(valY, 0, 1023, 0, 180);
servY.write(servYPoz);
moving();
}
void moving(){
switch(key){
case '5':
ServPravo();
break;
case '4':
ServLevo();
break;
case '3':
ServCentr();
break;
}
}
void ServPravo(){
servXPoz = 0;
servYPoz = 0;
servX.write(servXPoz);
servY.write(servYPoz);
}
void ServLevo(){
servXPoz = 180;
servYPoz = 0;
servX.write(servXPoz);
servY.write(servYPoz);
}
void ServCentr(){
servXPoz = 90;
servYPoz = 0;
servX.write(servXPoz);
servY.write(servYPoz);
}
Korbofos » 27 янв 2017, 18:31
Подскажите как передать массив из еprom по у указателю в функцию
- Код: Выделить всё • Развернуть
eeprom char pfone_num[12];
void ip_send(char *str);
ip_send(pfone_num); //так ничего не получается
}
CvAVR
loox » 28 янв 2017, 00:56
Korbofos
CVAvr:
Доступ в EEPROM, проиводится путем использования глобальных переменных с ключевым словом eeprom.
В Вашем случае удобнее использовать указатель, который будет храниться в SRAM
пример:
eeprom int data; // целая переменная, которая храниться в eeprom
void main(void)
{
int as; // целое , будет храниться в SRAM
int eeprom *pointToEeprom; // объявление указателя eeprom, сам указатель будет храниться в SRAM
data = 53; // пример прямой записи значения в eeprom
// пример, косвенная запись того же значения с использованием указателя
pointToEeprom =&data;
*pointToEeprom = 98;
as = data; //пример, непосредственное чтение из eeprom
as = *pointToEeprom; // пример, чтение с использованием указателя
}
За сим все. Спасибо loox
Добавлено спустя 2 часа 51 минуту 48 секунд:
Dr.Unk
коллега
При передаче данных между двумя устройствами, необходимо точно спроектировать протокол передачи данных:
<data><data1>,<data2>,......<признак окончания посылки>
data - byte 1 байт
data1 - int 2 байта
data2 - byte 1 байт
.....
/n - признак окончания строки
Варианты: длина посылки фиксированная, тогда при приеме можно не контролировать признак откончания строки, как в Вашем случае, и вообще его не передавать
длина строки переменная, тогда при ПРИЕМЕ необходимо проверять каждый принятый байт на признак окончания посылки.
ОЧЕНЬ ВАЖНО При передаче посылки между устройствами передаются байты. Прием данных возможен только в буфер byte или char. Обработка данных, в Вашем случае, должна начаться только после приема всей пачки данных.
Теперь о Вашей программе:
Вам будет удобнее использовать функцию приема SerialEvent, посмотрите примеры Communication - SerialEvent
С помощью этой функции вы легко организуете протокол приема данных, как при фиксированной длине , так и при ожидании признака окончания пачки данных.
При приеме используйте буфер byte (непонятно почему у Вас char)
int будет передан двумя байтами - сначала, по моему старший разряд первым,потом младший (извини не помню, проверь при тесте)
тогда int = BYTEn*256+BYTEn+1
Применяемая вами функция:
sscanf(buffer, "%[^','],%[^','],%s", &strX, &strY, &key);
работает с char а вы переслали int в виде 2-х byte в шеснадцатеричном виде.
Можно еще один Вариант - в передатчике вместо строки Serial.print(X) - напишите Serial.print(X,DEC) , тогда будете перtдавать char(ы)
Если, что то непонятно аписал, переспросите
Спасибо loox
rgusev » 07 июн 2017, 02:22
Коллеги.
Вопрос к специалистам.
Есть старый станок ЧПУ "Кулибин 1"
Контроллер у него вот этот
http://fablabs.ru/wiki/index.php/0409 Кто может сказать можно ли
1. Перепрограммировать и распараллелить каналы? Сейчас там три запараллеленых канала. По 2 фишки на X Y и Z
2. Как то сконнектить его со "стандартными" программами управления? Или подскажите с чем она будет нормально работать.
А то родная МНТЦ-шная убогая какая то.
Madf » 07 июн 2017, 12:41
1. Перепрограммировать можно, сделать тоже (что угодно). Вопрос будите ли этим заморачиваться т.к. ответ в втором пункте.
2. Можно "сконектить". Вся проблема в Г-код движке и обвесе железа (куда, что подключено). На это всё надо обладать недюжинными знаниями или искать готовое решение в поиске, например вот что-то есть:
http://mntc.livejournal.com/8448.html
Dairis » 11 июн 2017, 10:25
Vsem privet. Nuzna pomosh. Neophadimo vstroits v prosivku vuzigatelja stolbik sravnitelnix velecin i izmenenije skorosti zavisimosti ot zagruzennix dannix. Jesli jests kto mozet pomoc, pozalosta napesiti mnje
dairis_kadikis@inbox.lv i ja vislu neophadimije faili... za rannije sposibo!!!
к561ЛА7 » 14 июн 2017, 01:10
требуется сгенерировать иплульс положительной полярности частотой 100 герц
запускаю таймер т0 в режиме стс, на частоте 7813 герц, и ститаю до 78, потом вроде должно сбрасываться
генератор начального кода кодвижн авр генерит код
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
// Mode: CTC top=OCR0
// OC0 output: Set on compare match
TCCR0=0x3D;
TCNT0=0x00;
OCR0=0x2D;
в прерывании
// Timer 0 output compare interrupt service routine
interrupt [TIM0_COMP] void timer0_comp_isr(void)
{
// как обычно запускаю таймер и ножку порта ставлю в 1
TCCR1A = 0x00; //stop timer
TCCR1B = 0x00; //stop timer
TCNT1 = 0x01; //
TCCR1B = 0b00000100; //start timer
PORTB.1 = 1; //
}
а в основном цикле жду когда таймер досчитает и ставлю ножку в 0
if (5>TCNT1){ //
PORTB.1 = 0;} //
вроде бы все должно работать...
а оно не работает ! нет импульсов на осцилографе..
заколебался уже
vvk74 » 14 июн 2017, 08:05
В начале идёт инициализация т0, а в прерываниии почему-то т1. И с импульсами лучше pwm использовать на таймере т1
к561ЛА7 » 14 июн 2017, 23:49
vvk74 писал(а):В начале идёт инициализация т0, а в прерываниии почему-то т1. И с импульсами лучше pwm использовать на таймере т1
идея была в том, чтобы запустить таймер ТО, с частотой 7813, и сбрасывать его когда он досчитает до 78, чтобы получилась частота прерывания 100 герц, и в этом прерывании устанавливать ножку порта в 1, , запускать таймер Т1, а когда он немного посчитает, ставить ножку порта в 0.
а какой pwm использовать на таймере т1 чтобы получить шим с частотой 100 герц и скажностью примерно 50 ?