Подключение китайского парктроника на 8 датчиков к arduino.
- Войдите на сайт для отправки комментариев
Приветствую всех, нужно сигнал DATA с блока парктроника расшифровать в ардуино ... если подцепиться осцилографом то получаем следующую картину: длинный импульс (2мс), видимо как синхросигнал, потом 49 импульсов (имеются импульсы 0.1 мс и 0.2мс - широкий и узкий) ... широкий - логическая единица, узкий - ноль ... между концом и началом повторения сигнала идет пробел в 25 мс. Не могу считать и выдать эти данные в порт ... а все потому что не могу разобраться и понять код, что и зачем здесь в параметрах и как это связано))) ...
#include <TimerOne.h>
#define LEDPIN 13 // Вывод светодиода
#define BTNPIN 2
#define BUFFER_LENGTH 100
volatile uint16_t startImpuls;
volatile uint16_t lengthImpuls;
volatile uint16_t timerCount=0;
byte buffPos = 0;
byte Buffer[BUFFER_LENGTH];
byte packet[4];
byte posInPacket=0;
byte startBYTE = 15;
void setup()
{ /*
LOW — вызов прерывания всякий раз, когда на порту низкий уровень напряжения;
CHANGE – прерывание вызывается при изменении значения на входе;
RISING – вызов прерывания при изменении уровня напряжения с низкого (LOW) на высокое(HIGH)
FALLING – вызов прерывания при изменении уровня напряжения с высокого (HIGH) на низкое (LOW)
*/
startImpuls=0;
lengthImpuls=0;
pinMode(BTNPIN, INPUT);
for(int i=0; i< BUFFER_LENGTH; i++)
Buffer[i]=0;
Serial.begin(115200);
Timer1.initialize(20);
Timer1.attachInterrupt(callback); // attaches callback() as a timer overflow interrupt
attachInterrupt(0, fireUp, RISING);
}
void callback() { timerCount++; }
void loop()
{
if (lengthImpuls > 0)
{
uint16_t temp=0;
uint16_t li = lengthImpuls;
lengthImpuls=0;
//--------------------------//
// получена приамбула "1 1 1 1"
if (li >50 && li <60)
{
posInPacket =0;
}
// Расчитываю позицию массиве
temp = posInPacket / 8;
uint16_t bitPos = posInPacket;
// Разворачиваю позицию для метода bitSet(x,n)
bitPos = 7 - bitPos;
if (bitPos >= 8)
{
bitPos = posInPacket - (8*temp);
}
// Получен "0"
if (li >4 && li <6)
{
posInPacket ++;
}
// Получен "1"
else if (li >10 && li <15)
{
bitSet(packet[temp],bitPos);
posInPacket ++;
}
//digitalWrite(13,LOW);
// Отправить пакет "большему брату"
if (posInPacket > 15)
{
detachInterrupt(0);
// Serial.println("------");
for(int i=0; i<4; i++)
{
Serial.print(packet[i], BIN);
Serial.print(" ");
packet[i]=0;
}
Serial.println("");
posInPacket = 0;
attachInterrupt(0, fireUp, RISING);
}
//--------------------------//
}
}
// Функция обработки прерывания на подъем
void fireUp()
{
detachInterrupt(0);
startImpuls = timerCount;
attachInterrupt(0, fireDown, FALLING);
}
// Функция обработки прерывания на подъем
void fireDown()
{
detachInterrupt(0);
lengthImpuls = timerCount - startImpuls;
startImpuls=0;
timerCount=0;
attachInterrupt(0, fireUp, RISING);
}
///////////////////////////////////////////////////////////////////////////////////////////////
для всего этого пользовался данными темы: http://arduino.ru/forum/apparatnye-voprosy/rebyata-pomogite-podklyuchit-datchiki-parkovki-ot-parktronika-k-arduino?page=3
С осцила, так выглядит сигнал на DATA, парктроника
//////////////////////////////////////////////////////////////////////
Так выглядит серия сигналов
///////////////////////////////////////////////////////
Начало посылки ...
///////////////////////////////////////////////
Конец посылки ...
Если расшифровать данные как я описал выше получаем следующее:
синхро сигнал, далее:
Ну с этим я думаю разберусь когда получу массив ... но не могу понять как эти данные выудить ардуиной (выше код, для 4х датчикового парктроника и у него другие параметры ... длинна короткого длинного импульса и пр, как его подстроить под себя не знаю)
#include <TimerOne.h> #define BTNPIN 2 // Вход сигнала #define TEST 13 // Тест #define BUFFER_LENGTH 100 // длинна буфера volatile uint16_t startImpuls; volatile uint16_t lengthImpuls; volatile uint16_t timerCount=0; byte buffPos = 0; // позиция буфера byte Buffer[BUFFER_LENGTH]; // длиннпа буфера byte packet[50]; // хз, разиер пакета byte posInPacket=0; // позиция входящего пакета byte startBYTE = 15; // стартовый байт int dat; void setup() { /* LOW — вызов прерывания всякий раз, когда на порту низкий уровень напряжения; CHANGE – прерывание вызывается при изменении значения на входе; RISING – вызов прерывания при изменении уровня напряжения с низкого (LOW) на высокое(HIGH) FALLING – вызов прерывания при изменении уровня напряжения с высокого (HIGH) на низкое (LOW)*/ startImpuls=0; lengthImpuls=0; pinMode (TEST, OUTPUT); for(int i=0; i< BUFFER_LENGTH; i++) Buffer[i]=0; Serial.begin(115200); Timer1.initialize(20); // Интервал срабатывания таймера 1мс Timer1.attachInterrupt(callback); attachInterrupt(0, fireUp, RISING); // Запуск таймера при наличии сигнала LOW // Замеряем только низкий уровень сигнала } void callback() { timerCount++; } void loop() { if (lengthImpuls > 0) { uint16_t temp=0; uint16_t li = lengthImpuls; lengthImpuls=0; if (li > 1.5 && li < 2.5) // При сигнале длинной 2мс начало пакета digitalWrite(13, LOW); if (li > 0.07 && li < 0.13) // При сигнале длинной 0.1мс соответствует - 0 digitalWrite(13, LOW); if (li > 0.17 && li < 0.23) // При сигнале длинной 0.2мс соответствует - 1 digitalWrite(13, HIGH); Serial.println (li, DEC); // Отправляем в порт для тестового просмотра } } // Функция обработки прерывания на подъем void fireUp() { detachInterrupt(0); startImpuls = timerCount; attachInterrupt(0, fireDown, FALLING); } // Функция обработки прерывания на падение void fireDown() { detachInterrupt(0); lengthImpuls = timerCount - startImpuls; startImpuls=0; timerCount=0; attachInterrupt(0, fireUp, RISING); }Делал когда то человеку. Да, 49 бит на входе. Тоже длительности измерял, но уже не помню что к чему.)
#include <TimerOne.h> #define BTNPIN 2 // Вход сигнала #define TEST 13 // Тест #define BUFFER_LENGTH 100 // длинна буфера volatile uint16_t startImpuls; volatile uint16_t lengthImpuls; volatile uint16_t timerCount=0; byte buffPos = 0; // позиция буфера byte Buffer[BUFFER_LENGTH]; // длиннпа буфера byte packet[50]; // хз, разиер пакета byte posInPacket=0; // позиция входящего пакета byte startBYTE = 15; // стартовый байт int dat; void setup() { /* LOW — вызов прерывания всякий раз, когда на порту низкий уровень напряжения; CHANGE – прерывание вызывается при изменении значения на входе; RISING – вызов прерывания при изменении уровня напряжения с низкого (LOW) на высокое(HIGH) FALLING – вызов прерывания при изменении уровня напряжения с высокого (HIGH) на низкое (LOW)*/ startImpuls=0; lengthImpuls=0; pinMode (TEST, OUTPUT); for(int i=0; i< BUFFER_LENGTH; i++) Buffer[i]=0; Serial.begin(115200); Timer1.initialize(20); // Интервал срабатывания таймера 1мс Timer1.attachInterrupt(callback); attachInterrupt(0, fireUp, RISING); // Запуск таймера при наличии сигнала LOW // Замеряем только низкий уровень сигнала } void callback() { timerCount++; } void loop() { if (lengthImpuls > 0) { uint16_t temp=0; uint16_t li = lengthImpuls; lengthImpuls=0; if (li > 95 && li < 100) // При сигнале длинной 2мс начало пакета Serial.println(); if (li > 3 && li < 6) // При сигнале длинной 0.1мс соответствует - 0 {Serial.print("0"); Serial.print(" ");} if (li > 8 && li < 12) // При сигнале длинной 0.2мс соответствует - 1 {Serial.print("1"); Serial.print(" ");} // Serial.println (li, DEC); // Отправляем в порт для тестового просмотра } } // Функция обработки прерывания на подъем void fireUp() { detachInterrupt(0); startImpuls = timerCount; attachInterrupt(0, fireDown, FALLING); } // Функция обработки прерывания на падение void fireDown() { detachInterrupt(0); lengthImpuls = timerCount - startImpuls; startImpuls=0; timerCount=0; attachInterrupt(0, fireUp, RISING); }#include <TimerOne.h> #define BTNPIN 2 // Вход сигнала #define TEST 13 // Тест #define BUFFER_LENGTH 100 // длинна буфера volatile uint16_t startImpuls; volatile uint16_t lengthImpuls; volatile uint16_t timerCount=0; byte buffPos = 0; // позиция буфера byte Buffer[BUFFER_LENGTH]; // длиннпа буфера byte packet[50]; // хз, разиер пакета byte posInPacket=0; // позиция входящего пакета byte startBYTE = 15; // стартовый байт int dat; void setup() { /* LOW — вызов прерывания всякий раз, когда на порту низкий уровень напряжения; CHANGE – прерывание вызывается при изменении значения на входе; RISING – вызов прерывания при изменении уровня напряжения с низкого (LOW) на высокое(HIGH) FALLING – вызов прерывания при изменении уровня напряжения с высокого (HIGH) на низкое (LOW)*/ startImpuls=0; lengthImpuls=0; pinMode (TEST, OUTPUT); for(int i=0; i< BUFFER_LENGTH; i++) Buffer[i]=0; Serial.begin(115200); Timer1.initialize(20); // Интервал срабатывания таймера 1мс Timer1.attachInterrupt(callback); attachInterrupt(0, fireUp, RISING); // Запуск таймера при наличии сигнала LOW // Замеряем только низкий уровень сигнала } void callback() { timerCount++; } void loop() { if (lengthImpuls > 0) { uint16_t temp=0; uint16_t li = lengthImpuls; lengthImpuls=0; if (li > 95 && li < 100) // При сигнале длинной 2мс начало пакета Serial.println(); if (li > 3 && li < 6) // При сигнале длинной 0.1мс соответствует - 0 {Serial.print("0"); Serial.print(" ");} if (li > 8 && li < 12) // При сигнале длинной 0.2мс соответствует - 1 {Serial.print("1"); Serial.print(" ");} // Serial.println (li, DEC); // Отправляем в порт для тестового просмотра } } // Функция обработки прерывания на подъем void fireUp() { detachInterrupt(0); startImpuls = timerCount; attachInterrupt(0, fireDown, FALLING); } // Функция обработки прерывания на падение void fireDown() { detachInterrupt(0); lengthImpuls = timerCount - startImpuls; startImpuls=0; timerCount=0; attachInterrupt(0, fireUp, RISING); }ооо спасибо)) сегодня занят по работе, как время появится попробую))
Делал когда то человеку. Да, 49 бит на входе. Тоже длительности измерял, но уже не помню что к чему.)
блин, печально)) и кода и пр. не сохранилось?))
согласно последнему коду, получилось рассмотреть код лучше ... в итоге пришел к выводу что точное расстояние этот парктроник не показывает, только расстояние к примеру - от 5 до 30 одно и тоже значение ... от 30 до 60 другое... от 60 и до 130 третье ... нуи само собой есть препятствие или нет совсем ... походу придется выкидывать МК и цеплять вместо МК ардуино, и уже писать совсем другой код)) ... буду думать как поступить ...
... походу придется выкидывать МК и цеплять вместо МК ардуино
переведи...
Ну МК это что? Это так... А вот АРДУИНО... Это сила)!
вангую, ТС хотел зацепиться к сигналу штатного контроллера системы парктроника, но его это не устроило . И он решил, сам управлять ультразвуковыми датчиками от ардуино, без этого штатного контроллера.
Но ведь как то этот парктроник показывает десятки метра ? или там шкала с квадратиками? или вообще чисто звуком пищит? Но даже шкала не должна так грубо работать по 0,4м. Вроде минимум 0,1м
вангую, ТС хотел зацепиться к сигналу штатного контроллера системы парктроника, но его это не устроило . И он решил, сам управлять ультразвуковыми датчиками от ардуино, без этого штатного контроллера.
Но ведь как то этот парктроник показывает десятки метра ? или там шкала с квадратиками? или вообще чисто звуком пищит? Но даже шкала не должна так грубо работать по 0,4м. Вроде минимум 0,1м
так и есть))) либо выкинуть контроллер в блоке парктроника и там расшифровывать (подключить дуню) ... либо вообще выкинуть блок парктроника и купить платки от JSN-SR04T ... по 170 за платку нашел ... нужно 8 ...
_____________
этот парктроник показывает по 4 деления на каждый датчик ... вот они и есть)) - без препятствия и 4 уровня с препятствием ... на дисплее 8 сегментов ... 4 лево 4 право ... причем он даже не показывает спереди препятствие или сзади ... в коде ... код одинаковый что для переда что для зада ... просто питание приходит в блок разное
блин, печально)) и кода и пр. не сохранилось?))
Почему нет? "У нас все ходы записаны.")
Глянул. Ардуино транслирует сигналы с 2х парктроников (8 датчиков) в UART на 9600.
Почему нет? "У нас все ходы записаны.")
Глянул. Ардуино транслирует сигналы с 2х парктроников (8 датчиков) в UART на 9600.
а у меня походу UART не пашет, даже тестовые не работают))) ... Друг программист помог, по коду выше сделать))
#include <TimerOne.h> #define BTNPIN 2 // Вход сигнала #define TEST 13 // Тест //#define BUFFER_LENGTH 100 // длинна буфера volatile uint16_t startImpuls; volatile uint16_t lengthImpuls; volatile uint16_t timerCount=0; byte buffPos = 0; // позиция буфера //byte Buffer[BUFFER_LENGTH]; // длиннпа буфера byte packet[8]; // хз, разиер пакета byte posInPacket=0; // позиция входящего пакета byte startBYTE = 15; // стартовый байт //int dat; void setup() { /* LOW — вызов прерывания всякий раз, когда на порту низкий уровень напряжения; CHANGE – прерывание вызывается при изменении значения на входе; RISING – вызов прерывания при изменении уровня напряжения с низкого (LOW) на высокое(HIGH) FALLING – вызов прерывания при изменении уровня напряжения с высокого (HIGH) на низкое (LOW)*/ startImpuls=0; lengthImpuls=0; pinMode (TEST, OUTPUT); //for(int i=0; i< BUFFER_LENGTH; i++) // Buffer[i]=0; Serial.begin(115200); Timer1.initialize(20); // Интервал срабатывания таймера 1мс Timer1.attachInterrupt(callback); attachInterrupt(0, fireUp, RISING); // Запуск таймера при наличии сигнала LOW // Замеряем только низкий уровень сигнала } void callback() { timerCount++; } void loop() { int i=0; uint16_t dist=0; uint16_t li=0; bool firstbit=true; uint8_t data[8]; uint8_t sensorindex=0; while(true) { if (lengthImpuls > 0) { // uint16_t temp=0; li = lengthImpuls; lengthImpuls=0; if (li > 90) // При сигнале длинной 2мс начало пакета { i=0; Serial.print("\n"); for(int b=0;b<4;b++) { Serial.print(data[b]); Serial.print(" "); data[b]=0; } Serial.print(" "); firstbit=true; sensorindex=0; } else if (!firstbit) { if(i>7) { i=0; sensorindex++; } if (li > 7) // При сигнале длинной 0.1мс соответствует - 0 bitSet(data[sensorindex],7-i); i++; } else firstbit=false; } } } // Функция обработки прерывания на подъем void fireUp() { detachInterrupt(0); startImpuls = timerCount; attachInterrupt(0, fireDown, FALLING); } // Функция обработки прерывания на падение void fireDown() { detachInterrupt(0); lengthImpuls = timerCount - startImpuls; startImpuls=0; timerCount=0; attachInterrupt(0, fireUp, RISING); }в общем по этому коду получаем значения)) 0 - препятствие впритык, (потом зона не чувствительности до 25 см, всегда - 0), потом 3 - 30см, 4-40, 5-50 и так далее до 14 ... это условно опять же))
_________
MaksVV, оказался прав делений куда больше) чем 5-30, 30-60 и так далее)) как раз каждые 10 см примерно ...
Макс, ты же вот с машинами возишься. Если два экземпляра едут друг другу навстречу парктрониками - у приборов башню не сносит? Они же должны издавать сигналы, которые будут пересекаться во времени и пространстве.
китайское гавно для доп.установки да, бывает пищит невпопад. У ори не замечал такого. Ну парковочники же на скорости не работают. (Собственно поэтому такое развитие событий не такое уж и частое). А при парковке, если две машины в лоб едут, возможно да, будут глючно работать радары. Но, я думаю, более вероятно, что в момент глюка будет показывать, что препятствие есть, хотя реально его нет, чем наоборот.
Я этим паркам не особенно то доверяю. С ними расслабляешься и меньше глядишь в зеркала. А видят они далеко не всё. Хотя на моей машине их просто нет, зато есть фаркоп)) Жена тут сдавала назад, слышит хрусь. Берёзку сломала диаметром см 7, прям шаром фаркопа упёрлась , вот это радар.
PS есть камера заднего вида, но она почему-то не всегда работает. Сапожник без сапог, как обычно...
А теперь вопрос знающим)) ... как эти данные вывести на дисплей? если я где-то вмешиваюсь в код, то и в порте начинает слать херню парктроник) ... нужно в какой то формат их перевести чтобы вывести по I2C? ну типо создать переменные и привязать к ним значения получаемые в мониторе порта? ... в общем я не понимаю куда вмешаться чтобы данные с парктроника не менялись ... если вклиниваюсь вне расчетов то пишет мол переменная отсылаемая в порт неизвестна ... и не компилируется
Использую в коде только 3 библиотеки
#include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // ширина в пикселях #define SCREEN_HEIGHT 32 // высота в пикселях #define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin) Adafruit_SSD1306 display(OLED_RESET); void setup() { display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Инициализирует дисплей. Адрес 0x3C для 128x32 example_draw_text(); //выводим текст } void loop() { } void example_draw_text(void) { display.clearDisplay(); //очищаем дисплей display.setTextSize(3); //размер букв display.setTextColor(WHITE); //цвет букв display.setCursor(0,0); //координаты текста display.println("04:28"); //текст display.display(); //выводим на дисплей все, что было задано }простой скетч, по выводу на дисплей текста)
#include <SPI.h> #include <TimerOne.h> //библиотека счетчика #include <Wire.h> #include <Adafruit_GFX.h> //библиотека графического дисплея #include <Adafruit_SSD1306.h> //библиотека OLED дисплея #define OLED_RESET 7 //пин сброса дисплея Adafruit_SSD1306 display(OLED_RESET); // #define BTNPIN 2 // Вход DATA c парктроника #define TEST 13 // Тестовый светодиод volatile uint16_t startImpuls; volatile uint16_t lengthImpuls; volatile uint16_t timerCount=0; void setup() { /* LOW — вызов прерывания всякий раз, когда на порту низкий уровень напряжения; CHANGE – прерывание вызывается при изменении значения на входе; RISING – вызов прерывания при изменении уровня напряжения с низкого (LOW) на высокое(HIGH) FALLING – вызов прерывания при изменении уровня напряжения с высокого (HIGH) на низкое (LOW)*/ startImpuls=0; lengthImpuls=0; pinMode (TEST, OUTPUT); Serial.begin(115200); Timer1.initialize(20); // Интервал срабатывания таймера 1мс Timer1.attachInterrupt(callback); attachInterrupt(0, fireUp, RISING); // Запуск таймера при наличии сигнала LOW display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // инициализация дисплея по интерфейсу I2C, адрес 0x3C) display.clearDisplay(); // очистка дисплея display.setTextSize(2); //размер букв display.setTextColor(WHITE); //цвет букв display.setCursor(0,0); //координаты текста //example_draw_text(); } void callback() {timerCount++;} void loop() { //display.println(12); //display.display(); //interrupts(); TIME(); //noInterrupts(); OLED(); } ///////////////////// Функция обработки прерывания на подъем void fireUp() { detachInterrupt(0); startImpuls = timerCount; attachInterrupt(0, fireDown, FALLING); } ///////////////////// Функция обработки прерывания на падение void fireDown() { detachInterrupt(0); lengthImpuls = timerCount - startImpuls; startImpuls=0; timerCount=0; attachInterrupt(0, fireUp, RISING); } ////////////////////// Функция обработки полученных данных void TIME() { int i=0; uint16_t dist=0; uint16_t li=0; bool firstbit=true; uint8_t data[8]; uint8_t sensorindex=0; while(true) { if (lengthImpuls > 0) { li = lengthImpuls; lengthImpuls=0; if (li > 90) // Сигнал начала пакета { i=0; Serial.print("\n"); for(int b=0;b<4;b++) { Serial.print(data[b]); Serial.print(" "); data[b]=0; } Serial.print(" "); firstbit=true; sensorindex=0; } else if (!firstbit) { if(i>7) { i=0; sensorindex++; } if (li > 7) // При сигнале длинной 0.1мс соответствует - 0 bitSet(data[sensorindex],7-i); i++; } else firstbit=false; } } } /////////////////////// Вывод на дисплей void OLED(void) { display.println(data[1]); //текст display.display(); }имеется такой код, ругается на нижнюю часть (в самом низу) на data[1], типо не найдено ... если эту строчку вставить в код для обработки полученных данных с парктроника то он выводит то что нужно, но сбивается таймер и рушит все вычисления ... а если вставляю куда либо в другое место то не находит ... как выдернуть эти данные не затронув цикл обработки. Еще, если в войд луп указать часть олед после тимер, на дисплей ничего не выводится даже просто цифра 1 .. а если написать строчку вывода до тимер, т о выводится все норм ...
Андрей, судя по жаргону- обьяснять что-либо бессмысленно, походу вы полный ноль в программировании...
поэтому просто примите как данность - этот код на экран ничего выводить не будет, даже если вы исправите ошибку с data[]
Андрей, судя по жаргону- обьяснять что-либо бессмысленно, походу вы полный ноль в программировании...
поэтому просто примите как данность - этот код на экран ничего выводить не будет, даже если вы исправите ошибку с data[]
Так и есть) ... не задавая глупых вопросов - ничему не научишься) ... а вам сложно подсказать? или хотя бы направить в нужное русло? раз уж вы понимаете в чем ошибка ... как обойти сбитие таймера - скажите
походу вы полный ноль в программировании...
могу написать прогу по радиоуправлению двигателем и светодиодом, могу написать многоуровневую менюшку с флагами для сенсорного цветного графического дисплея ... и пр ... могу вывести данные с датчика и так далее ... но я не разу не работал с этой библиотекой таймеров.
я не знаю, о каком "таймере" вы говорите, но дело не в нем...
Зачем Вы вставили цикл while(true) в ЛУП (строка 89) ? - из этого цикла у вас в программе нет выхода, один раз попав в него, программа зависнет там и уже никогда не попадет в процедуру OLED(). Поэтому у вас и нет вывода на экран.
я не знаю, о каком "таймере" вы говорите, но дело не в нем...
Зачем Вы вставили цикл while(true) в ЛУП (строка 89) ? - из этого цикла у вас в программе нет выхода, один раз попав в него, программа зависнет там и уже никогда не попадет в процедуру OLED(). Поэтому у вас и нет вывода на экран.
ого, не знал)) думаю почему после этого цикла ничего не прилетает)) ... это друг написал часть кода, я не знал что делает while:) спасибо, пошел курить на эту тему))
Зачем Вы вставили цикл while(true) в ЛУП (строка 89) ? - из этого цикла у вас в программе нет выхода, один раз попав в него, программа зависнет там и уже никогда не попадет в процедуру OLED(). Поэтому у вас и нет вывода на экран.
в общем ушел от того кода, ибо не знаю как избавиться от While, ничего не нарушив в работе ... вернулся к изначальному, но сравнив эти два кода получил это:
#include <TimerOne.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 // ширина в пикселях #define SCREEN_HEIGHT 32 // высота в пикселях #define OLED_RESET 4 // сброс дисплея #define LEDPIN 13 // Вывод светодиода #define BTNPIN 2 #define BUFFER_LENGTH 100 volatile uint16_t startImpuls; volatile uint16_t lengthImpuls; volatile uint16_t timerCount=0; byte buffPos = 0; byte Buffer[BUFFER_LENGTH]; byte packet[8]; byte posInPacket=0; byte startBYTE = 20; Adafruit_SSD1306 display(OLED_RESET); void setup() { /* LOW — вызов прерывания всякий раз, когда на порту низкий уровень напряжения; CHANGE – прерывание вызывается при изменении значения на входе; RISING – вызов прерывания при изменении уровня напряжения с низкого (LOW) на высокое(HIGH) FALLING – вызов прерывания при изменении уровня напряжения с высокого (HIGH) на низкое (LOW) */ display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Инициализирует дисплей. Адрес 0x3C для 128x32 display.clearDisplay(); //очищаем дисплей display.setTextSize(3); //размер букв display.setTextColor(WHITE); //цвет букв display.setCursor(0,0); //координаты текста startImpuls=0; lengthImpuls=0; pinMode(BTNPIN, INPUT); for(int i=0; i< BUFFER_LENGTH; i++) Buffer[i]=0; Serial.begin(115200); Timer1.initialize(20); Timer1.attachInterrupt(callback); // attaches callback() as a timer overflow interrupt attachInterrupt(0, fireUp, RISING); } void callback() { timerCount++; } void loop() {display.clearDisplay(); scanner (); // OLED(); } // Функция обработки прерывания на подъем void fireUp() { detachInterrupt(0); startImpuls = timerCount; attachInterrupt(0, fireDown, FALLING); } // Функция обработки прерывания на подъем void fireDown() { detachInterrupt(0); lengthImpuls = timerCount - startImpuls; startImpuls=0; timerCount=0; attachInterrupt(0, fireUp, RISING); } // Преобразования void scanner() { if (lengthImpuls > 0) { uint16_t temp=0; uint16_t li = lengthImpuls; lengthImpuls=0; if (li >90) {posInPacket = 2;} // Начало пакета temp = posInPacket / 8; // Расчитываю позицию массиве uint16_t bitPos = posInPacket; bitPos = 7 - bitPos; // Разворачиваю позицию для метода bitSet(x,n) if (bitPos >= 8) {bitPos = posInPacket - (8*temp);} if (li <7) {posInPacket ++;} // Получен "0" else if (li >8) {bitSet(packet[temp],bitPos); posInPacket++;} // Получен "1" if (posInPacket > 49) {detachInterrupt(0); // Отправить пакет "большему брату" for(int i=0; i<8; i++) {Serial.print(packet[i], BIN); Serial.print(" "); /*display.print(packet[i], DEC); display.display();*/ packet[i]=0;} //выводим на дисплей все, что было задано Serial.println(""); posInPacket = 47; attachInterrupt(0, fireUp, RISING);} } } // Дисплей /*void OLED() { display.print(packet[2], DEC); display.display();}*/проблема сейчас в следующем ... после начала "контрольной суммы" идет лишний бит, потом идут 4 партии по 8 бит на датчик ( по байту на датчик) ... дак вот из за этого лишнего бита вначале ... три датчика (2 3 4) показывают правильно, а первый фигню гонит ... можете подсказать как исключить один, первый бит? т. е. начиная со второго считать 4 пакета по 8 бит ... данные получаю вот такие:
первые 4 столбца данные о расстоянии с датчиков ... все должны быть одинаковые) если поставить препятствие впритык должны быть 4 столбца нолей, с тремя так и происходит, первый меняется но не ноль выдает ... (есть конечно сбои в значениях, недочеты в коде и пр, но думаю их можно будет потом отфильтровать перед выводом на дисплей и т д ...