Извращение по цифровому входу
- Войдите на сайт для отправки комментариев
Ср, 17/02/2021 - 13:56
Вообщем немного извращения в ветку...
Имеется - ардуино с одним свободным цифровым входом, и 16 битная, инвертированная шина данных на скорости 4800...
Задача - при поступлении определенного (два пакета) сигнала зажечь (грубо говоря) светодиод сигнализации...
Идеи предложения или хоть направления?!
а название у этой шины есть?
Поймал фронт, и пошел проверять с заданной частотой что на входе. Получил 2 байта, сравнил с заданными.
" и 16 битная, инвертированная шина данных на скорости 4800..." А это к чему?
Если вам нужен однопроводной канал связи - так и скажите. Но, тут должны быть другие требования.
Имеется - ардуино
Какая? И что за свободный пин? На нём есть прерывание, хоть какое-нибудь?
Задача - при поступлении определенного (два пакета) сигнала зажечь (грубо говоря) светодиод сигнализации...
Идеи предложения или хоть направления?!
Если ответ на предыдущий вопрос "да", то "как два пальца", даже хороший пример кода есть готовый - в библиотеке SoftwareSerial в той её части, которая занимается чтением Rx.
Общая идея:
1. Считаете длительность бита BIT_DURATION = F_CPU / BAUD / (F_CPU/1000000). Для 16МГц и 4800 bod это 206 микросекунд.
2. Пин притягиваете к уровню противоположному уровню стартового бита.
3. ждёте прерывания на пине (это будет начало стартового бита).
4. Ждёте ровно половину длительности бита BIT_DURATION / 2. В этот момент Вы в середине передачи стартового бита.
5. Заводите таймер на срабатывание (по COMPA, например) с интервалом BIT_DURATION
Теперь Вы будете получать прерывания от таймера в момент "середины" каждого передаваемого бита.
6. Ловите прерывания и считываете с пина соответствующие биты.
7. Когда всё считали, выключаете прерывание - Вы получили результат.
Следующий байт (слово) читается также.
P.S. Не знаю, что там у Вас за шина, но 90 пудов для неё можно приспособить сам SofwareSerial (может, с минимальными переделками) и ничего писать не надо.
Если ответ на предыдущий вопрос "да", то "как два пальца", даже хороший пример кода есть готовый - в библиотеке SoftwareSerial в той её части, которая занимается чтением Rx.
Спасибо за конструктив буду курить!
Стандартный uart Arduino поддерживает только восьмибитный пакет данных...
Softwareserial может поддерживать 16 бит?
...буду курить!
Стандартный uart Arduino поддерживает только восьмибитный пакет данных... Softwareserial может поддерживать 16 бит?
Лучше курите.
P.S. Не знаю, что там у Вас за шина, но 90 пудов для неё можно приспособить сам SofwareSerial
Шина одна линия из двух стандартных UART с длинной "слова" 16 бит...
Дрова.)
Сегодня посмотрю, что и как....
Постараюсь разобраться!
Несколько букв? Только что то стопа не видать.
линия инвертированная...
Ну а если в конец второго байта посмотреть.
Особенность общения, стоповые в конце передачи пакетов не показываются...
А задачи какие ещё крутятся?
Да, плевать на стопы. Лишь бы стартовый был. В #4 я расписал как это делается. SoftSerial делает именно это.
К сожалению слабоумием страдаю.... не могу понять SoftSerial от слова совсем...
А вот не лазил бы я в SoftSerial. Что мешает просто принимать по 2 байта им же?
Что мешает просто принимать по 2 байта им же?
Мешает то, что при 16-битной посылке никто не пошлёт стартовый бит в начале второго байта (если я правильно понял протокол).
К сожалению слабоумием страдаю.... не могу понять SoftSerial от слова совсем...
Найдите там строки (у меня они №№ 157-165)
1
// Read each of the 8 bits
2
for
(uint8_t i=8; i > 0; --i)
3
{
4
tunedDelay(_rx_delay_intrabit);
5
d >>= 1;
6
DebugPulse(_DEBUG_PIN2, 1);
7
if
(rx_pin_read())
8
d |= 0x80;
9
}
А также выше строку, в которой описана d (у меня она №142).
d нужно переописать как uint16_t, в цикле, вместо i=8 написать i=16. Наконец, вместо "d |= 0x80;" поставить "d |= 0x8000;"
Собственно всё, к концу цикла Вы должны получить все 16 бит.
Дальше надо посмотреть - там идёт участок функции в которой они складывают результат в буфер и пропускают стоповый бит. Оно Вам надо? Или не надо? Разбирайтесь сами и соответственно принимайте решение.
Мешает то, что при 16-битной посылке никто не пошлёт стартовый бит в начале второго байта (если я правильно понял протокол).
Я смотрел файл с расширением h а не срр...
должно получиться так?
142
uint16_t d = 0;
143
144
// If RX line is high, then we don't see any start bit
145
// so interrupt is probably not for us
146
if
(_inverse_logic ? rx_pin_read() : !rx_pin_read())
147
{
148
// Disable further interrupts during reception, this prevents
149
// triggering another interrupt directly after we return, which can
150
// cause problems at higher baudrates.
151
setRxIntMsk(
false
);
152
153
// Wait approximately 1/2 of a bit width to "center" the sample
154
tunedDelay(_rx_delay_centering);
155
DebugPulse(_DEBUG_PIN2, 1);
156
157
// Read each of the !16 bits
158
for
(uint16_t i=16; i > 0; --i)
159
{
160
tunedDelay(_rx_delay_intrabit);
161
d >>= 1;
162
DebugPulse(_DEBUG_PIN2, 1);
163
if
(rx_pin_read())
164
d |= 0x8000;
165
}
Такие изменения в библиотеке повлияют на другие UART устройства? или возможно выдернуть часть кода и юзать отдельно без вреда других устройств?
Я бы сделал копию библиотеки и переименовал бы её, чтобы никому другому не мешать.
А так-то, примерно оно, проверять надо. Ну и с дальнейшим кодом до конца этой функции надо разобраться что с ним делать и нужен ли он. Там идёт складывание в буфер и пропуск стопового бита. Может сделать буфер из uint16_t и в него складывать, это уже от задачи зависит - как удобнее, так и надо делать.
Спасибо, будем разбираться...
Можно безо всяких библиотек. А не устроит, тогда думать дальше. SoftwareSerial практически и так все прерывания запрещает.
Я бы сделал копию библиотеки и переименовал бы её, чтобы никому другому не мешать.
очень сложно! манагер PCINTов отсутствует как класс однако...
очень сложно! манагер PCINTов отсутствует как класс однако...
PCINT вообще отсутствует в концепции Ардуино. И именно потому, что просто - не получится.
С другой стороны, никто ведь не мешает переписать логику и на "обычные" прерывания.
"просто" вообще не бывает, а pcint просто часть инструмента, было бы желание /знания.
а название у этой шины есть?
человек реверсит шину SL-DATA сигнализаций старлайн. Эта шина использовалась на сигнализациях вплоть до А94. Служит для расширения функционала сигнализации до GSM/GPS, посредством подключения внешнего GSM модуля.
Желание есть а знания нуль... По этому и хотелось сделать именно прием сообщения не с помощью стандартного UART, а как нибудь по другому... Используя часть кода через прерывание считать пакет данных и сделать вывод из этого авария или всё норм и посылать свои команды...
Понравилось идея ЕвгенийП... Но знаний не хватает от слова совсем...
Но знаний не хватает от слова совсем...
Ну так это совершенно стандартная ситуация.
И из нее также совершенно стандартные 3 варианта выхода:
1. Расширять свои знания и умения до тех пор, пока их не будет хватать.
2. Заказать работу тем, у кого знаний и умений хватает.
3. Забыть об этой задаче.
Желание есть а знания нуль... По этому и хотелось сделать именно прием сообщения не с помощью стандартного UART, а как нибудь по другому... Используя часть кода через прерывание считать пакет данных и сделать вывод из этого авария или всё норм и посылать свои команды...
Понравилось идея ЕвгенийП... Но знаний не хватает от слова совсем...
Если SoftwareSerial не используется в скетче то как рекомендовал Евгений вполне, а если используется придётся править библиотеку, ограничивая используемые под сериал пины, но переносить правленную в папку скетча, чтобы не затронуть остальные проекты
SoftwareSerial используется в скетче, с двумя устройствами, SIM800 и периферией... кроме того есть желание подцепить GPS модуль GY-NEO6MV2 (но пока только желание)...
А собственно возможно написать "деревянный" код не используя функцию UART от слова совсем??? сделать то же самое с получением данных и складыванием...
SoftwareSerial используется в скетче, с двумя устройствами...
SoftwareSerial работает максимум с одним устройством. И то не без проблем.
Если Вам нужно более одного UART, следует выбирать контроллер, в котором есть соответствующее количество аппаратных портов.
Может ли работать такой кот?
001
byte
slin = 11;
//Назначение входа RX SL-Data
002
unsigned
int
rx16bit = 0;
//Назначение переменной данных SL-Data
003
unsigned
int
rx16bit1 = 0;
//Назначение переменной первого слова
004
unsigned
int
rx16bit2 = 0;
//Назначение переменной второго слова
005
void
setup
() {
006
pinMode(slin, INPUT);
//Инициализируем вход для приема данных из сигнализации.
007
digitalWrite(slin, HIGH);
//притягиваем к плюсу
008
009
void
loop
() {
010
011
if
(digitalRead (slin) == LOW) {
//Условие срабатывания считывания кода
012
rx16bit = 0;
013
if
(digitalRead (slin) == HIGH) {
//Ждем стартовый импульс (не уверен что это вообще будет работать)
014
delayMicroseconds(312);
//Отсчитываем полтора импульса (208+104мкс)
015
if
(digitalRead (slin) == HIGH) {
//Смотрим состояние первого бита
016
rx16bit + 0;
//Если высокий уровень то нулик
017
}
else
{
018
rx16bit + 1;
//Если низкий уровень то прибавляем бит в десятичном виде
019
}
020
delayMicroseconds(208);
//Отсчитываем импульс (208 мкс)
021
if
(digitalRead (slin) == HIGH) {
//Смотрим состояние следующего бита
022
rx16bit + 0;
//Если высокий уровень то нулик
023
}
else
{
024
rx16bit + 2;
//Если низкий уровень то прибавляем бит в десятичном виде
025
}
026
delayMicroseconds(208);
//Отсчитываем импульс (208 мкс)
027
if
(digitalRead (slin) == HIGH) {
//Смотрим состояние следующего бита
028
rx16bit + 0;
//Если высокий уровень то нулик
029
}
else
{
030
rx16bit + 4;
//Если низкий уровень то прибавляем бит в десятичном виде
031
}
032
delayMicroseconds(208);
//Отсчитываем импульс (208 мкс)
033
if
(digitalRead (slin) == HIGH) {
//Смотрим состояние следующего бита
034
rx16bit + 0;
//Если высокий уровень то нулик
035
}
else
{
036
rx16bit + 8;
//Если низкий уровень то прибавляем бит в десятичном виде
037
}
038
delayMicroseconds(208);
//Отсчитываем импульс (208 мкс)
039
if
(digitalRead (slin) == HIGH) {
//Смотрим состояние следующего бита
040
rx16bit + 0;
//Если высокий уровень то нулик
041
}
else
{
042
rx16bit + 16;
//Если низкий уровень то прибавляем бит в десятичном виде
043
}
044
delayMicroseconds(208);
//Отсчитываем импульс (208 мкс)
045
if
(digitalRead (slin) == HIGH) {
//Смотрим состояние следующего бита
046
rx16bit + 0;
//Если высокий уровень то нулик
047
}
else
{
048
rx16bit + 32;
//Если низкий уровень то прибавляем бит в десятичном виде
049
}
050
delayMicroseconds(208);
//Отсчитываем импульс (208 мкс)
051
if
(digitalRead (slin) == HIGH) {
//Смотрим состояние следующего бита
052
rx16bit + 0;
//Если высокий уровень то нулик
053
}
else
{
054
rx16bit + 64;
//Если низкий уровень то прибавляем бит в десятичном виде
055
}
056
delayMicroseconds(208);
//Отсчитываем импульс (208 мкс)
057
if
(digitalRead (slin) == HIGH) {
//Смотрим состояние следующего бита
058
rx16bit + 0;
//Если высокий уровень то нулик
059
}
else
{
060
rx16bit + 128;
//Если низкий уровень то прибавляем бит в десятичном виде
061
}
062
delayMicroseconds(208);
//Отсчитываем импульс (208 мкс)
063
if
(digitalRead (slin) == HIGH) {
//Смотрим состояние следующего бита
064
rx16bit + 0;
//Если высокий уровень то нулик
065
}
else
{
066
rx16bit + 256;
//Если низкий уровень то прибавляем бит в десятичном виде
067
}
068
delayMicroseconds(208);
//Отсчитываем импульс (208 мкс)
069
if
(digitalRead (slin) == HIGH) {
//Смотрим состояние следующего бита
070
rx16bit + 0;
//Если высокий уровень то нулик
071
}
else
{
072
rx16bit + 512;
//Если низкий уровень то прибавляем бит в десятичном виде
073
}
074
delayMicroseconds(208);
//Отсчитываем импульс (208 мкс)
075
if
(digitalRead (slin) == HIGH) {
//Смотрим состояние следующего бита
076
rx16bit + 0;
//Если высокий уровень то нулик
077
}
else
{
078
rx16bit + 1024;
//Если низкий уровень то прибавляем бит в десятичном виде
079
}
080
delayMicroseconds(208);
//Отсчитываем импульс (208 мкс)
081
if
(digitalRead (slin) == HIGH) {
//Смотрим состояние следующего бита
082
rx16bit + 0;
//Если высокий уровень то нулик
083
}
else
{
084
rx16bit + 2048;
//Если низкий уровень то прибавляем бит в десятичном виде
085
}
086
delayMicroseconds(208);
//Отсчитываем импульс (208 мкс)
087
if
(digitalRead (slin) == HIGH) {
//Смотрим состояние следующего бита
088
rx16bit + 0;
//Если высокий уровень то нулик
089
}
else
{
090
rx16bit + 4096;
//Если низкий уровень то прибавляем бит в десятичном виде
091
}
092
delayMicroseconds(208);
//Отсчитываем импульс (208 мкс)
093
if
(digitalRead (slin) == HIGH) {
//Смотрим состояние следующего бита
094
rx16bit + 0;
//Если высокий уровень то нулик
095
}
else
{
096
rx16bit + 8192;
//Если низкий уровень то прибавляем бит в десятичном виде
097
}
098
delayMicroseconds(208);
//Отсчитываем импульс (208 мкс)
099
if
(digitalRead (slin) == HIGH) {
//Смотрим состояние следующего бита
100
rx16bit + 0;
//Если высокий уровень то нулик
101
}
else
{
102
rx16bit + 16384;
//Если низкий уровень то прибавляем бит в десятичном виде
103
}
104
delayMicroseconds(208);
//Отсчитываем импульс (208 мкс)
105
if
(digitalRead (slin) == HIGH) {
//Смотрим состояние следующего бита
106
rx16bit + 0;
//Если высокий уровень то нулик
107
}
else
{
108
rx16bit + 32768;
//Если низкий уровень то прибавляем бит в десятичном виде
109
if
(rx16bit1 == 0) {
110
rx16bit1 = rx16bit;
111
}
else
{
112
rx16bit2 = rx16bit;
113
}
114
}
115
}
116
}
117
118
}
Пинать прошу не сильно...
Может ли работать такой кот?
Любой код, всегда работает и делает именно то, что написал программист (неисправность аппаратуры мы сейчас не рассматриваем). Так что, да, этот код, вне всякого сомнения, будет работать и будет делать именно то, что в нём написано.
Будет ли он делать то, чего Вы от него ждёте?
Ну, Вы не написали что конкретно Вы ожидаете, но если мои догадки о назначении этого кода верны, то нет - не будет.
1
rx16bit + 1;
//Если низкий уровень то прибавляем бит в десятичном виде
И куда деваем результат "прибавления"?
На ум кладём, очевидно...
Хочу получить следующий результат...
При возникновении сигнала как на картинке в первом сообщении считать его и получить десятичные данные в переменных rx16bit1 и rx16bit2...
Далее планируется сравнивать данные с тем что заложено будет в программе и по результатам "говорить" что пришло...
Вопрос о работоспособности в начале кода... После появления нуля на шине, будет ли ожидание положительного импульса? На 13 строке... То есть будет ли закыкливание? Или программа пойдет шагать дальше? Думаю сделать запрет на прерывания при работе этого кода...
Вопрос о работоспособности в начале кода...
Ответьте сами себе на вопрос из последнего предложения #36
Если под такой записью
1
rx16bit + 16;
ты понимаешь прибавление к переменной числа, то в языке С это записывается иначе:
1
rx16bit += 16;
На это и намекали выше, но ты не исправил, следовательно не описка, а печальная реальность.
===========
Скорее всего, уровень твоих познаний в программировании вообще, и языке С - в частности, не позволит тебе решить поставленную задачу. Уж больно ошибка "говорящая" ;))) Не стоит обижаться.
Спасибо за подсказку, завтра обязательно поправлю...
Я и пишу в песочницу... Обижаться и не думал...
Если внесу данное исправление то получу необходимый результат?
Или же нужно ещё вносить корректировки???
Или же нужно ещё вносить корректировки???
Пока не может идти речи о твоем "коде". Пока стоит изучить язык программирования. Или обращаться в коммерческий раздел форума, если программирование тебя не интересует.
Скачай КиР (Керниган и Ричи, к примеру https://www.r-5.org/files/books/computers/languages/c/kr/Brian_Kernighan_Dennis_Ritchie-The_C_Programming_Language-RU.pdf), открой любую онлайн ИДЕ (их - десятки, яндекс первой выдает https://ideone.com - ничем не хуже других), читай книжку и делай примеры. Нет другого пути.
Обожаю такие советы... Но... Работа у меня в другом формате... И стараюсь такие советы не давать... А давать конкретные объяснения... Но и за литературу спасибо, почитаю...
Спасибо за подсказку, завтра обязательно поправлю...
Я и пишу в песочницу... Обижаться и не думал...
1.Если внесу данное исправление то получу необходимый результат?
2.Или же нужно ещё вносить корректировки???
ОК. Давай по твоему.
1. Нет, не получишь.
2. Да, нужно.
-----------------
Ты спросишь: какие? На этот вопрос тебе уже 40 с гаком сообщений ответили, ты их не понимаешь. Об этом я и написал выше.
Я не знаю, в чем ты специалист, но, кажется, придумал универсальную аналогию: НЕВОЗМОЖНО объяснить, как приготовить плов, если человек не умеет жарить даже яичницу.
почитал тему по диагонали (пока некогда вникать). Спрошу у общественности, а наличие свободного аппаратного UART (взять мегу 2560) облегчит задачу?
почитал тему по диагонали (пока некогда вникать). Спрошу у общественности, а наличие свободного аппаратного UART (взять мегу 2560) облегчит задачу?
а то!
Какое то? Нестандартный 16-битный UART.
почитал тему по диагонали (пока некогда вникать). Спрошу у общественности, а наличие свободного аппаратного UART (взять мегу 2560) облегчит задачу?
я так понял, там на два байта один стартовый бит, по стоповым не понятно. ну и биты инвертированы. Найду такую сигналку , тоже поисследую