Помогите разобраться с скетчем
- Войдите на сайт для отправки комментариев
Чт, 04/09/2014 - 21:28
Ребята помогите разобраться с скетчем. Нашел вот такой проект(металлоискатель):http://robocraft.ru/blog/projects/2994.html
Реализовал на Arduino Uno, работает. Загружаю скетч в Arduino nano 3.0 и тишина, почему понять не могу. Вообшем вопрос: Где в скетче обозначен pin 5, и как его переназначить?
// Connect search coil oscillator (20-200kHz) to pin 5
// Connect piezo between pin 13 and GND
// Connect NULL button between pin 12 anf GND
// REMEMBER TO PRESS NULL BUTTON AFTER POWER UP!!
#define SET(x,y) (x |=(1<<y)) //-Bit set/clear macros
#define CLR(x,y) (x &= (~(1<<y))) // |
#define CHK(x,y) (x & (1<<y)) // |
#define TOG(x,y) (x^=(1<<y)) //-+
unsigned long t0=0; //-Last time
int t=0; //-time between ints
unsigned char tflag=0; //-Measurement ready flag
float SENSITIVITY= 1000.0; //-Guess what
//-Generate interrupt every 1000 oscillations of the search coil
SIGNAL(TIMER1_COMPA_vect)
{
OCR1A+=1000;
t=micros()-t0;
t0+=t;
tflag=1;
}
void setup()
{
pinMode(13,OUTPUT); //-piezo pin
digitalWrite(12,HIGH); //-NULL SW. pull up
//-Set up counter1 to count at pin 5
TCCR1A=0;
TCCR1B=0x07;
SET(TIMSK1,OCF1A);
}
//-Float ABS
float absf(float f)
{
if(f<0.0)
return -f;
else
return f;
}
int v0=0; //-NULL value
float f=0; //-Measurement value
unsigned int FTW=0; //-Click generator rate
unsigned int PCW=0; //-Click generator phase
unsigned long timer=0; //-Click timer
void loop()
{
if(tflag)
{
if(digitalRead(12)==LOW) //-Check NULL SW.
v0=t; //-Sample new null value
f=f*0.9+absf(t-v0)*0.1; //-Running average over 10 samples
tflag=0; //-Reset flag
float clf=f*SENSITIVITY; //-Convert measurement to click frequency
if(clf>10000)
clf=10000;
FTW=clf;
}
//-Click generator
if(millis()>timer)
{
timer+=10;
PCW+=FTW;
if(PCW&0x8000)
{
digitalWrite(13,HIGH);
PCW&=0x7fff;
}
else
digitalWrite(13,LOW);
}
}
http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukomment...
....тут народ крутой :) - могут и побить.....
:)
http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukomment...
....тут народ крутой :) - могут и побить.....
:)
Ну я новичек, пока еще не крутой) Примите в свою групировку, стану)
я не из крутых :) - но тему изучите !!!!!!!!!!! код легче смотреть будет... многие текст, как вы загрузили, - и смотреть не будут
у нано от уно различий - аналоговых входов 8 а не 6.... остальные различия - не важны ( питание, микроUSB ), т.е. скетчи для уно пригодны без переделки и для нано....
в IDE не забыли ли указать тип прошиваемой платки ?
поморгать светиком - для проверки наны - пробовали ?
Текст исправлю как разберусь. Нано работает(моргает). Тип платки указал. Вопрос всетаки остается открытым где и как определен PIN 5?
5-ый пин определен не в явной форме
если я правильно помню,то это настройка таймера
вообщем перенастроить можно но не на любую ножку,а кажеться только на те которые выдают прерывания по таймеру
5-ый пин определен не в явной форме
если я правильно помню,то это настройка таймера
Спасибо за ответ. Теперь только осталось узнать ножка D5 у нано выполняет ту же функцию(таймер), что и на Uno...
Datasheet вам в помощь :)
> (PCINT21/OC0B/T1) PD5
- как вам и сказали в #5 - счётчик_1 управляет етой ногой ( зависит от его настроек )
> Текст исправлю как разберусь.
.....не нано его править - нано его правильно на СЮДА разместить !
http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukomment...
> Теперь только осталось узнать ножка D5 у нано выполняет ту же функцию(таймер), что и на Uno...
........да , но ето задача 328, а не уно или нано
читайте #4 и #8 !!!!!!!!!! :)-
5-ый пин определен не в явной форме
если я правильно помню,то это настройка таймера
вообщем перенастроить можно но не на любую ножку,а кажеться только на те которые выдают прерывания по таймеру
перенастроить НЕЛЬЗЯ - ибо так сделали камень.... можно взять другой счётчик - 0 или 2 - но ето не перенастройка будет, а геморрой ( когда в ТОМ месте 128 зубов - и все болят )
Всем спасибо. Буду дальше разбираться почему этот скетч не работает в нано.
ну хз че вы там делаете
TCCR1B=0x07; CS12 CS11 CS10 = 1 1 1 - External clock source on T1 pin. Clock on rising edge.
.... пин 5 назначили входом счётчика Т1 , фронт импульсов - нарастающий
код рабочий - будет и на нано работать, надо схемку всю проверить
>вопрос - что и где устанавливает макрос SET(TIMSK1,OCF1A);
Вы не поверите, он устанавливает бит OCF1A в регистре TIMSK1 в единицу (вообщем этот макрос - полное дублирование сатндартного макроса bitSet)
А вот что к чему приведет установка этого бита в этом регистре: это уже открывать даташит на конкретный камень. именно тот который стоит в конкретной плате - и смотреть. Находитие TIMSK1 и смотрите какие биты у него есть и что они означают.
А по поводу "изначальной задачи", так немного странно. По идее и UNO и nano - на одном камне сделаны. Следовательно, теоретически - они с точки зрения скетча это вообще "неразличимые".
Так что мне кажется это где-то или брак, или невнимательно собрали или, как всегда "проблемы с питанием".
Вы не поверите, он устанавливает бит OCF1A в регистре TIMSK1 в единицу - ВОТ И НЕ ВЕРЮ....
:)
и по С++ , если можно вопрос....
у TIMSK1 нет бита OCF1A... , но есть бит OCIE1A
и по С++ , если можно вопрос....
Это не "конструкции" непонятные. А вы не знаете битовых операций.
Возмите учебник какой-нибудь и почитайте про них.
Или хотя-бы в справочничек (но может быть не достаточно)
http://arduino.cc/en/Reference/BitwiseAnd
http://arduino.cc/en/Reference/Bitshift
потом почитайте что такое #define , что-бы понять что же он в итоге делает.
Конечно конструкция будет не понятной, если операторов не понимаешь. Как можно понять целое, если составные части "какая-то магия".
у TIMSK1 нет бита OCF1A... , но есть бит OCIE1A
это именно из ТО 328.... !!!!!!!!!!!!!!!!!!!
про магию наборов символов - буду искать книжку :(
Кстати, если вы думаете, что имя OCF1A это "нечто особенное", то вы ошибаетесь.
Это просто "человеческое имя". Для некоего бита.
Просто, что-бы не запоминать что "первый бит у регистра TIMSK1" имеет такой-то смысл, ему просто "дали имя".
Просто что-бы не запоминать "какой он там по счету". Просто синоним цифры B00000001. И не более.
Поэтому, SET(TIMSK1,OCF1A) , это АБСОЛЮТНО тоже самое, что написать SET(TIMSK1,1);
Можно вообще свои имена придумать
#define MY_CONFIGURATION_BIT_OF_TIMER_FOR_COOL_FEATURE 1
и потом использовать так:
SET(TIMSK1,MY_CONFIGURATION_BIT_OF_TIMER_FOR_COOL_FEATURE);
И результат будет - абсолютно такой же.
Все будет работать - точно так же.
А вы будете рассказывать, что у TIMSK1 - нет бита MY_CONFIGURATION_BIT_OF_TIMER_FOR_COOL_FEATURE
Если объявлю, то будет.
Регистр, вообще ничего про никакие имена не знает. У него есть нулевой бит, первый, второй, третий... и т.п.
А уж "как их обзывать", это либо "исторически сложилось", либо "раз производитель в документации так называет, то и программеры такое же наименование используют, что-бы путаницы меньше было" и т.д. и т.п.
3 - ????????????????? 4 - ??????????????
Навскидку (лень уже думать), 3 - проверка "бит Y установлен?", 4 - инверсия бита
я знаю и понимаю отдельные действия над двоичными числами.... но не могу понять и найти - как работают такие наборы
(x |=(1<<y)
x &= (~(1<<y))
x & (1<<y)
x^=(1<<y)
.........(x |=(1<<y) - это же можно записать 3...4-мя строками ( в каждой строке - по одному оператору ) ?
....вот и подумал, что подскажете.... но если вам проще отослать к литературе, чем в 5 строк рассказать - я пойду к литературе, спасибо
у TIMSK1 нет бита OCF1A... , но есть бит OCIE1A
это именно из ТО 328.... !!!!!!!!!!!!!!!!!!!
ну, а разве у атмеги 328-мь нет OCF1A бита?
Есть. Ищу в даташите OCF1A. Смотрю что это такое? Это "бит один ...." (и пофиг чего). Это синоним цифры 1.
Сомневаетесь? Перепроверте меня: сделайте поиск по папке ардуино слова "OCF1A" и найдите как он объявлен.
Для соотвествующего камня. Например я нашел в файле iom328p.h
Или еще проще, сделайте Serial.println(OCF1A,BIN) и посмотретие чему же он равен.
Значит SET(TIMSK1,OCF1A) будет устанавливать первый бит регистра TIMSK1.
К чему это привидет? А к тому, что указанно в даташите. Идем в даташит. Находим описание TIMSK1 и видим, что первый бит отвечает за "Timer/Counter1, Output Compare A Match Interrupt Enable"
И да, в даташите он "обозван" как OCIE1A и логичней было-бы использовать это имя при установке.
Но, еще раз OCF1A и OCIE1A это просто два синонима для слов "первый бит". Их можно взаимозаменять, или писать цифру 1 - результат будет один и тот же.
Но 328 камне, устанавливать первый бит используя имя-синоним OCF1A, вместо OCIE1A можно только либо "по опечатке", либо что-бы закипятить мозг тому кто будет этот код читать.
А компилятору - пофиг. И то и другое имя известно/объвялено. И то и другое равно единице.
Кстати, если вы думаете, что имя OCF1A это "нечто особенное", то вы ошибаетесь.
Это просто "человеческое имя". Для некоего бита.
Просто, что-бы не запоминать что "первый бит у регистра TIMSK1" имеет такой-то смысл, ему просто "дали имя".
Просто что-бы не запоминать "какой он там по счету". Просто синоним цифры B00000001. И не более.
Поэтому, SET(TIMSK1,OCF1A) , это АБСОЛЮТНО тоже самое, что написать SET(TIMSK1,1);
Можно вообще свои имена придумать
#define MY_CONFIGURATION_BIT_OF_TIMER_FOR_COOL_FEATURE 1
и потом использовать так:
SET(TIMSK1,MY_CONFIGURATION_BIT_OF_TIMER_FOR_COOL_FEATURE);
И результат будет - абсолютно такой же.
Все будет работать - точно так же.
А вы будете рассказывать, что у TIMSK1 - нет бита MY_CONFIGURATION_BIT_OF_TIMER_FOR_COOL_FEATURE
Если объявлю, то будет.
Регистр, вообще ничего про никакие имена не знает. У него есть нулевой бит, первый, второй, третий... и т.п.
А уж "как их обзывать", это либо "исторически сложилось", либо "раз производитель в документации так называет, то и программеры такое же наименование используют, что-бы путаницы меньше было" и т.д. и т.п.
полностью согласен.... НО - в том коде - нету определения явного бита_1 регистра TIMSK1 - что он OCIE1A , почему компилятор не реагирует на то - КАКИЕ БИТЫ в регистре TIMSK1 мы хотим установить-сбросить ?
3 - ????????????????? 4 - ??????????????
Навскидку (лень уже думать), 3 - проверка "бит Y установлен?", 4 - инверсия бита
спасибо и про навскидку :) - это и хотел услышать - проверка-инверсия.... пойду усваивать, спасибо
я знаю и понимаю отдельные действия над двоичными числами.... но не могу понять и найти - как работают такие наборы
(x |=(1<<y)
Ну так пошагово разбирайте эти отдельные действия. На бумажке. На примерах. А как же иначе разобратсья.
Возмите, для примера каких-то "два числа". И попытайтесь их поставить и посчитать, что получится.
Скажем x=194, y=3
И попробуйте посчтитать "что получится". Читать , естественно начинаем "с правой стороны".
Подствялем y. Что будет результатом выражения (1<<3)? Какой число? А в двоичной форме записе?
у TIMSK1 нет бита OCF1A... , но есть бит OCIE1A
это именно из ТО 328.... !!!!!!!!!!!!!!!!!!!
ну, а разве у атмеги 328-мь нет OCF1A бита?
Есть. Ищу в даташите OCF1A. Смотрю что это такое? Это "бит один ...." (и пофиг чего). Это синоним цифры 1.
Сомневаетесь? Перепроверте меня: сделайте поиск по папке ардуино слова "OCF1A" и найдите как он объявлен.
Для соотвествующего камня. Например я нашел в файле iom328p.h
Или еще проще, сделайте Serial.println(OCF1A,BIN) и посмотретие чему же он равен.
Значит SET(TIMSK1,OCF1A) будет устанавливать первый бит регистра TIMSK1.
К чему это привидет? А к тому, что указанно в даташите. Идем в даташит. Находим описание TIMSK1 и видим, что первый бит отвечает за "Timer/Counter1, Output Compare A Match Interrupt Enable"
И да, в даташите он "обозван" как OCIE1A и логичней было-бы использовать это имя при установке.
Но, еще раз OCF1A и OCIE1A это просто два синонима для слов "первый бит". Их можно взаимозаменять, или писать цифру 1 - результат будет один и тот же.
Но 328 камне, устанавливать первый бит используя имя-синоним OCF1A, вместо OCIE1A можно только либо "по опечатке", либо что-бы закипятить мозг тому кто будет этот код читать.
А компилятору - пофиг. И то и другое имя известно/объвялено. И то и другое равно единице.
спасибо !!!!
типерь понятно - что для установки-сброса бита 3 в регистре TIMSK1 можно взять название бита 3 пофуй какого регистра ! НО это же бардак ?!!!!!!!
> Но 328 камне, устанавливать первый бит используя имя-синоним OCF1A, вместо OCIE1A можно только либо "по опечатке", либо что-бы закипятить мозг тому кто будет этот код читать.
......мине - закипятил до 300 гр. Ц - это уже пар :)
спасибо :)
полностью согласен.... НО - в том коде - нету определения явного бита_1 регистра TIMSK1 - что он OCIE1A , почему компилятор не реагирует на то - КАКИЕ БИТЫ в регистре TIMSK1 мы хотим установить-сбросить ?
А чего ему реагирвоать? КАКИЕ БИТЫ ВЫ УСТАНВЛИВАЕТЕ? Вы устанавливаете ПЕРВЫЙ БИТ. Бит с номером 1. Чего компилятору на это реагировать? Для компилятора TIMSK1 и OCIE1A - это "просто числа".
Ему достаточно знать чему равны эти числа.
Если скажем, я подключу к ардуине на D3 реле. А в коде напишу:
То потом тоже возмущатся, что "а почему компилятор не сказал, что у меня к ноге припаяно реле, а не светодиод"?
>НО - в том коде - нету определения явного бита_1 регистра TIMSK1 -
А это обратная сторона "простоты ардуины". Писали бы на чистом С, вам бы пришлось самому ручками, писать что-то типа
#define OCIE1A 1
или взять готовые заголовчные файлы, уже кем-то написанные и писать что-то типа
#include "iom328p.h" где все эти объявления кто-то уже сделал за вас.
Но, так как для "чайников" это слишком сложно. Особенно на старте. То ардуина сама, вам, взяла и подключила этот заголовчный файл.
Почему именно его? А помните, до того как компилировать вы указывали тип платы в меню? Вот. А выбирите другую плату (камень), у которой вообще нет имени OCIE1A в даташите, и компилятор вам завопит что "не знаю что это за фигня". Потому что подгключит другое файл, в котором OCEI1A не объвялен.
Он вам "кучу" всего подключает. Вас же не удивляет, что вы, скажем функкией digitalWrite() или delay() пользуетесь. А ведь тоже нигде ее не объввляли, бибилиотек не подключали.... просто arduinoIDE вам помогает. Что-бы проще было начать "диодами мигать".
я знаю и понимаю отдельные действия над двоичными числами.... но не могу понять и найти - как работают такие наборы
(x |=(1<<y)
Ну так пошагово разбирайте эти отдельные действия. На бумажке. На примерах. А как же иначе разобратсья.
Возмите, для примера каких-то "два числа". И попытайтесь их поставить и посчитать, что получится.
Скажем x=194, y=3
И попробуйте посчтитать "что получится". Читать , естественно начинаем "с правой стороны".
Подствялем y. Что будет результатом выражения (1<<3)? Какой число? А в двоичной форме записе?
естественно начинаем "с правой стороны" - мине не естесственно :( , откудова мине ето знать ?
итого - справо на лево - бит 3 устанавливаем в 1 ?
а присвоить и or - в каком порядке ?
типерь понятно - что для установки-сброса бита 3 в регистре TIMSK1 можно взять название бита 3 пофуй какого регистра !
Да. Но только ДЛЯ ЭТОГО КАМНЯ.
А потом ваш код ктонибудь попробует скомпильнуть под другой камень. А там скажем они будут равны не единице, а 2 и 4-ре.
И... все. Получили глюк (компилятор-то пропустит). Нужно было поставить 2-рой бит, а вы поставили 4-ртый (а компилятору откуда знать? Сказали четвертый - поставил четвертый).
НО это же бардак ?!!!!!!!
Ну почему? Если у меня есть такой псевдокод:
И что? Оба println выведут одно и тоже: 30 км. Абсолютно взаимозаменяемые строки.
По крайней мере пока скорость велосепидиста и расход бензина автомобиля совпадают числово. Бардак? Да. Но не в компиляторе или языке, а в голове того, кто вычисляет растояние умножая время на расход бензина что-бы вычислить "сколько проедет велосипедист".
полностью согласен.... НО - в том коде - нету определения явного бита_1 регистра TIMSK1 - что он OCIE1A , почему компилятор не реагирует на то - КАКИЕ БИТЫ в регистре TIMSK1 мы хотим установить-сбросить ?
А чего ему реагирвоать? КАКИЕ БИТЫ ВЫ УСТАНВЛИВАЕТЕ? Вы устанавливаете ПЕРВЫЙ БИТ. Бит с номером 1. Чего компилятору на это реагировать? Для компилятора TIMSK1 и OCIE1A - это "просто числа".
Ему достаточно знать чему равны эти числа.
Если скажем, я подключу к ардуине на D3 реле. А в коде напишу:
То потом тоже возмущатся, что "а почему компилятор не сказал, что у меня к ноге припаяно реле, а не светодиод"?
>НО - в том коде - нету определения явного бита_1 регистра TIMSK1 -
А это обратная сторона "простоты ардуины". Писали бы на чистом С, вам бы пришлось самому ручками, писать что-то типа
#define OCIE1A 1
или взять готовые заголовчные файлы, уже кем-то написанные и писать что-то типа
#include "iom328p.h" где все эти объявления кто-то уже сделал за вас.
Но, так как для "чайников" это слишком сложно. Особенно на старте. То ардуина сама, вам, взяла и подключила этот заголовчный файл.
Почему именно его? А помните, до того как компилировать вы указывали тип платы в меню? Вот. А выбирите другую плату (камень), у которой вообще нет имени OCIE1A в даташите, и компилятор вам завопит что "не знаю что это за фигня". Потому что подгключит другое файл, в котором OCEI1A не объвялен.
Он вам "кучу" всего подключает. Вас же не удивляет, что вы, скажем функкией digitalWrite() или delay() пользуетесь. А ведь тоже нигде ее не объввляли, бибилиотек не подключали.... просто arduinoIDE вам помогает. Что-бы проще было начать "диодами мигать".
я вас понял, и вы поймите мои заблуждения ( если оно вам нано ) - моя думал, что компилятор знает ( где-то там из глубин описаний ) , что у ЕТОГО регистра НЕТУ такого БИТА ( по имени ).....
типерь моя понял - что имя БИТА - это просто его порядковый номер в байте :)
естественно начинаем "с правой стороны" - мине не естесственно :( , откудова мине ето знать ?
ну может хотя-бы из какого-нибудь учебника по программированию? Ну первые же страницы. Там где расказывается что такое переменные, что такое оператор присваивания. Какие у него бывают сокращенные виды записи. Ну хоть какие-то азы прочитать. Ну хотя-бы "азбуку".
типерь понятно - что для установки-сброса бита 3 в регистре TIMSK1 можно взять название бита 3 пофуй какого регистра !
Да. Но только ДЛЯ ЭТОГО КАМНЯ.
А потом ваш код ктонибудь попробует скомпильнуть под другой камень. А там скажем они будут равны не единице, а 2 и 4-ре.
И... все. Получили глюк (компилятор-то пропустит). Нужно было поставить 2-рой бит, а вы поставили 4-ртый (а компилятору откуда знать? Сказали четвертый - поставил четвертый).
НО это же бардак ?!!!!!!!
Ну почему? Если у меня есть такой псевдокод:
И что? Оба println выведут одно и тоже: 30 км. Абсолютно взаимозаменяемые строки.
По крайней мере пока скорость велосепидиста и расход бензина автомобиля совпадают числово. Бардак? Да. Но не в компиляторе или языке, а в голове того, кто вычисляет растояние умножая время на расход бензина что-бы вычислить "сколько проедет велосипедист".
не дурите миня !!!! строка #5 выведет = 30 ( НО - км ) - сколько вы проедете за велопрогулку
а строка #7 выведет = 30 ( НО - литров ) - сколько съест ваше авто за 3 часа поездки
> Какие у него бывают сокращенные виды записи.
вот про это моя и не знал :( спасибо !
не дурите миня !!!! строка #5 выведет = 30 ( НО - км ) - сколько вы проедете за велопрогулку
а строка #7 выведет = 30 ( НО - литров ) - сколько съест ваше авто за 3 часа поездки
Пятница? Совмещаете ардуину с горячительными? Где вы видите в скетче вывод единиц измерения?
Он выведет цифру "30". А что это - это уже вы сами додумаете. Если вам сказали что "скетч выводит километры", то вы будете воспринимать это именно как "растояние велосипедиста. И даже число будет верное.
Ну хорошо. А если вот так будет в скетче:
Что он выведет? Где бардак? В компиляторе или голове?
не дурите миня !!!! строка #5 выведет = 30 ( НО - км ) - сколько вы проедете за велопрогулку
а строка #7 выведет = 30 ( НО - литров ) - сколько съест ваше авто за 3 часа поездки
Пятница? Совмещаете ардуину с горячительными? Где вы видите в скетче вывод единиц измерения?
Он выведет цифру "30". А что это - это уже вы сами додумаете. Если вам сказали что "скетч выводит километры", то вы будете воспринимать это именно как "растояние велосипедиста. И даже число будет верное.
Ну хорошо. А если вот так будет в скетче:
Что он выведет? Где бардак? В компиляторе или голове?
у вас в голове :) - это же вы прописали в строке #3 - "километры" :)-
> Где вы видите в скетче вывод единиц измерения?
это ясно из комментариев.... после объявлений переменных....
дааааааааа, согласен - компилятор не умеет читать их !
Пятница? - ДА
Совмещаете ардуину с горячительными? - НЕТ
....утром на сутки к самолётикам в Пулково.... тока чай....
Serial.print("S=");
Что он выведет? Где бардак? В компиляторе или голове?
у вас в голове :) - это же вы прописали в строке #3 - "километры" :)-
[/quote]
Верно. В голове. Того кто писал код. Точно так же как и в случае использование неверного имени бита.
Разница только в том, что я понимал что "пишу бред" :)
> А потом ваш код ктонибудь попробует скомпильнуть под другой камень.
.....а вот тогда бы компилятор и подсказал бы - что в етом регистре у этого камня такого бита НЕТУ !!!!!
.....нуууу, как есть - так и есть..... при переносе на другой камень - нуна думать :)