Блин. Не заметил :o
Спасибо.
Вид для печати
Извиняюсь за отсутствие :) у меня дочка родилась :) не до патронника :)
.
Я поправил плагин центрифуги. Я не довел до конца. сделал чтобы все работало.
Патронник я брал чтобы разобратся, использовать его не планирую. у меня в машине стоит Паркмастер хочу его прикрутить.
Чуть позже выложу сырцы плагина и последний работающий скетч ардуино .
Мои поздравления!!! Пусть дочь красавицей растет!!! :)
Поздравляю!!! Пусть растет здоровой и счастливой!
Могу оптимизировать скетчь, но без плагина и парктроника ни как :)
Парктроник закажу, а вот плагин с тебя.
Спасибо , за поздравления :)
Chip, для практического использования мне кажется этот парктронник не лучшее приобретение, чем дальше препятствие тем больше ошибок у этого прибора, хотя может алгоритмически это можно решить.
Это последний скетч на текущий момент.
В аттаче сырцы плагина с бинарником. плагин для центрифуги 3.1.PHP код:
#include <TimerOne.h>
#define LEDPIN 13 // Вывод светодиода
#define BTNPIN 2
#define START_FF_LEN 5
#define SEND_BUF_LEN 2
volatile uint16_t startImpuls;
volatile uint16_t lengthImpuls;
volatile uint16_t timerCount=0;
//byte buffPos = 0;
byte packet[SEND_BUF_LEN];
byte startArray[START_FF_LEN];
byte posInPacket=0;
byte startBYTE = 15;
void setup()
{ /*
LOW — вызов прерывания всякий раз, когда на порту низкий уровень напряжения;
CHANGE – прерывание вызывается при изменении значения на входе;
RISING – вызов прерывания при изменении уровня напряжения с низкого (LOW) на высокое(HIGH)
FALLING – вызов прерывания при изменении уровня напряжения с высокого (HIGH) на низкое (LOW)
*/
startImpuls=0;
lengthImpuls=0;
for(int i=0; i<START_FF_LEN;i++)
startArray[i]=0xff;
pinMode(BTNPIN, INPUT);
Serial.begin(115200);
Timer1.initialize(10);
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;
//Serial.println(li,DEC);
//return;
//--------------------------//
// получена приамбула "1 1 1 1"
if (li >100 && li <120)
{
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 >6 && li <15)
{
posInPacket ++;
}
// Получен "1"
else if (li >18 && li <40)
{
bitSet(packet[temp],bitPos);
posInPacket ++;
}
//digitalWrite(13,LOW);
// Отправить пакет "большему брату"
if (posInPacket > 15)
{
detachInterrupt(0);
// Если есть препятствие тогда посылаем пакет
// if ((packet[0] & 8) == 0)
Serial.write(startArray,START_FF_LEN); // массив приамбула
Serial.write(packet,SEND_BUF_LEN);
// сбрасываю буффер
for(int j=0;j<SEND_BUF_LEN;j++)
packet[j] = 0;
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);
}
это модифицированный офф. плагин. в нем пока жестко прописан порт COM6.
Алгоритм работы скетча следующий
подключение идет на порт D2
прерывание по фронту на подъем запоминаю значение счетчика
прерывание по фронту на спад вычисляю длину сигнала
для счетчика используется прерывание 1-го таймера поскольку при использовании прерываний по фронту функции времени перестают работать.
по приходу приамбулы начинаю парсить пакет.
на время передачи пакета по COM порту отписываюсь от прерываний, где то в инете читал что при использовании 0-го прерывания данные по порту COM могут подпортится.
сам пакет дополняю лишними 5ю байтами (0xFF) чтобы безошибочно прочитать пакет на компе (в случае если пакеты наложатся)
возможно надо понизить скорость порта в даташите на атмегу сказано что при большой скорости процент ошибок может достигать 2% и более.
Вот и я начал исследовать вот такой парктроник.
Начал по пути oops1 снимая сигнал через звуковую плату. Вот что получилось:
Вложение 11770
еще, крупнее-
Вложение 11771
и еще крупнее-
Вложение 11772
Возникает вопрос-а справится ли ардуино для считывания таких коротких импульсов, а конкретно скетч oops1?
0,5 мс не такой уж и короткий сигнал.
1 такт при кварце 16мГц равен 62 наносекунам.
Для лучшей точности я бы использовал таймер1 на прямую без библиотеки. Настроил его бы без пред делителя , его максимальное время получится 4мс, надеюсь у парктроника нет импульсов длинеее 4 мс , но если что всегда можно будет увеличить длительность отсчета до требуемой величины
В общем скетч на основе листинга oops1 для распознавания импульсов работает. Только я снимаю длительности "ноля". Так удобнее определить начала пакета.
Но, как оказалось, это не самая главная проблема. Проблема в том что я не могу "вычислить" протокол - не очень как то понятно "Ху ис ху". Понятно что все данные укладываются в один пакет, пакет всегда заканчивается "1". Где в нем данные расстояния, где признак датчика:confused:PHP код:
#include <TimerOne.h>
#define BTNPIN 2
volatile uint16_t startImpuls;
volatile uint16_t lengthImpuls;
volatile uint16_t timerCount=0;
byte posInPacket=0;
byte Packet[60];
byte startBYTE = 0;
void setup()
{ /*
LOW — вызов прерывания всякий раз, когда на порту низкий уровень напряжения;
CHANGE – прерывание вызывается при изменении значения на входе;
RISING – вызов прерывания при изменении уровня напряжения с низкого (LOW) на высокое(HIGH)
FALLING – вызов прерывания при изменении уровня напряжения с высокого (HIGH) на низкое (LOW)
*/
startImpuls=0;
lengthImpuls=0;
pinMode(BTNPIN, INPUT);
Serial.begin(115200);
Timer1.initialize(10);
Timer1.attachInterrupt(callback); // attaches callback() as a timer overflow interrupt
attachInterrupt(0, fireDown, FALLING);
}
void callback() { timerCount++; }
void loop()
{
if (lengthImpuls > 0)
{
uint16_t li = lengthImpuls;
lengthImpuls=0;
// получен стартовый импульс > 300
if (li > 200 && li < 400) {
startBYTE = 1;
// Serial.println("Start");
}
// Получен "1"
if (li >20 && li <50 && startBYTE == 1)
{
Packet[posInPacket] = 1;
posInPacket ++;
}
// Получен "0"
else if (li >60 && li <80 && startBYTE == 1)
{
Packet[posInPacket] = 0;
posInPacket ++;
}
// Отправить пакет "большему брату"
if (posInPacket > 56)
{
detachInterrupt(0);
for(int j=16;j<57;j++)
Serial.print(Packet[j],DEC);
Serial.println(" ");
posInPacket = 0;
startBYTE = 0;
attachInterrupt(0, fireUp, FALLING);
}
}
}
// Функция обработки прерывания на подъем
void fireUp()
{
detachInterrupt(0);
startImpuls = timerCount;
attachInterrupt(0, fireDown, RISING);
}
// Функция обработки прерывания на спад
void fireDown()
{
detachInterrupt(0);
lengthImpuls = timerCount - startImpuls;
startImpuls=0;
timerCount=0;
attachInterrupt(0, fireUp, FALLING);
}
Для примера прилагаю снятые данные пакета в разных режимах (на байты разделил условно):
Может у кого появятся мысли на этот счет?PHP код:
00000000 00000000 00000000 11010000 11010000 1 сенсор A --
01001100 00000000 00000000 00110000 01111100 1 сенсор A 60
10000000 00000000 00000000 11110000 00001000 1 сенсор A 20
00000000 00000000 00000000 00001101 00001101 1 сенсор B --
00000000 00000000 01010000 00000000 01010000 1 сенсор C --
00000000 00000000 00000101 00000000 00000101 1 сенсор D --
00000000 01111000 00001101 00000000 01110011 1 сенсор D 60
00000000 10000000 00001111 00000000 10001111 1 сенсор D 20
00000000 00000000 00000001 11101000 01101001 1 сенсоры A+D --
Ни у кого мыслей не появилось?...
В том то прикол что пакет идет один! Т.е. протокол кардинально отличается от твоего парктроника.
Насчет программной дешифрации все нормально. Я сравнивал пакеты, переведенные вручную и получаемые с ардуино - ошибок нет.
В своем сообщении я уже выкладывал пакет в разных режимах, еще раз повторю:
00000000 00000000 00000000 11010000 11010000 1 - подключен сенсор A, нет препятствий
01001100 00000000 00000000 00110000 01111100 1 - подключен сенсор A, примерно 60 см препятствие
10000000 00000000 00000000 11110000 00001000 1 - подключен сенсор A, примерно 20 см препятствие
ты приамбулу пакета вырезал ?
Я бы предположил что последние 2 тетрады это расстояние до препятствия
в 7-й тетраде 3 бит скорее всего флаг присуствия, первый и второй бит похоже идентификатор датчика.
выложи всетаки звуковые файлы, я верю тебе что ты читаеш правильно, просто мне так легче соображать, я на своем парктронике именно по звуковым файлам разобрался.
т.е. если подключен один датчик идет один пакет ?
Подключи остальные датчики и запиши что ходит
Да, вырезал, в преамбуле 10 импульсов.
Ок, вечером организую звуковые файлы.
Пакет один всегда, т.е. он повторяется один и тот же, вне зависимости от кол-ва датчиков. Естественно с разной информацией.
Возможен еще такой вариант, что байт на один сенсор, но тогда получается что у тебя препятствия на двух датчиках показывается а подключен один поэтому врядли этот вариант правильный.
Какой у тебя парктронник на сколько датчик , производитель. фото платы если есть.
Китайский, фотки есть, вечером из дома покажу.
Штатно у меня на машине стоит ПаркМастер на 4 сенсора, а этот я взял для экпериментов и установки на другой авто.
Похоже каждый китайский производитель свой протокол фигачит:rolleyes:
Нашел в тоем сообщении ранее указан был другой парктронник у него дисплей похож на мой паркмастер, корпус коробочки, провода и датчики, на мой парктронник китайский :)
Обшибся чуть-чуть - вот такой
Выкладываю:
Вложение 11933
По названиям файлов в принципе понятен режим. Например, D_0,3 - подключен датчик D, до припятствия - 0.3 м, C_P-_0,3 - датчик С, препятствие менее 0.3 м, далее - 0.3 м
p.s. на плате индикатора установлены м/сх
74HC164 - 8-bit serial-in, parallel-out shift register
EM78P153 - 8-bit microprocessor with low-power and high-speed CMOS technology
Если это как то может помочь расшифровке...
Я пока посмотрел 3 файла.
A--.wav
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1101 0000 1101 0000 1
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1101 0000 1101 0000 1
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1101 0000 1101 0000 1
D--.wav
0000 0000 0000 0000 0000 0000 0000 0000 0000 1101 0000 0000 0000 1101 1
0000 0000 0000 0000 0000 0000 0000 0000 0000 1101 0000 0000 0000 1101 1
0000 0000 0000 0000 0000 0000 0000 0000 0000 1101 0000 0000 0000 1101 1
D_0,3.wav
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1101 0000 1101 0000 1
0000 0000 0000 0000 0111 1000 0000 0000 0000 0000 1101 0000 1001 0100 1
0000 0000 0000 0000 0111 1000 0000 0000 0000 0000 1101 0000 1001 0100 1
Ты не ошибся с названием D_0,3.wav я бы сказал что A_0,3.wav
Возникла такая мысль. Проверь её сам, тут надо экспериментировать. На примере последней строки.
0000 0000 0000 0000 -- возможно приамбула надо уточнять
0111 1000 -- расстояние
0000 0000 0000 0000 1101 0000 -- ?
1001 0100 -- чексумма, возможно
1 -- конечный
Теперь что такое расстояние запись в стиле, почти, литл эндиан
тоесть чтобы получить расстояние нужно поменять местами 2 тетрады (тетрада - четыре бита)
1000 0111
биты в каждой тетраде нужно зеркалировать
0001 1110
Я посмотрел еще не все но пока возникла такая мысль
zhserg, ты куда пропал ? проверил ?
Не пропал я:). Все выходные прилаживал монитор в авто. Постараюсь сегодня.
Думаю можно уже wav не писать?
да, wav можно не писать :).
Мне интересно, правильное предположение или нет. Если нет, надо будет еще думать над ним.
Я в москве буду до конца недели а потом в отпуск :)
Очередные измерения:
С расстоянием теперь понятно:) 8 бит переворачиваем и получаем расстояние. 1 байт - левая сторона, 2 байт - правая (или наоборот:)).PHP код:
00000000 00000000 00000000 11010000 11010000 1 A -- (нет препятствия)
10000000 00000000 00000000 11010000 00001000 1 p- (<0.3)
01111000 00000000 00000000 11010000 11010100 1 A 0.3
00010100 00000000 00000000 11010000 11001100 1 A 0.4
01001100 00000000 00000000 11010000 10111100 1 A 0.5
00111100 00000000 00000000 11010000 11100010 1 A 0.6
01100010 00000000 00000000 11010000 10001010 1 A 0.7
00001010 00000000 00000000 11010000 11011010 1 A 0.8
01011010 00000000 00000000 11010000 10100110 1 A 0.9
00100110 00000000 00000000 11010000 11110110 1 A 1.0
01110110 00000000 00000000 11010000 10011110 1 A 2.0
00000000 00000000 00001101 00000000 00001101 1 D --(нет препятствия)
00000000 10000000 00001101 00000000 10001101 1 D p- (<0.3)
00000000 01111000 00001101 00000000 01110011 1 D 0.3
00000000 00010100 00001101 00000000 00011011 1 D 0.4
00000000 01001100 00001101 00000000 01000111 1 D 0.5
00000000 00111100 00001101 00000000 00110111 1 D 0.6
00000000 01100010 00001101 00000000 01101111 1 D 0.7
00000000 00001010 00001101 00000000 00000000 1 D 0.8
00000000 01011010 00001101 00000000 01010000 1 D 0.9
Он у тебя получается двух-зонный ?
т.е. слева 2 датчика и справа два датчика объеденены
Поизучал еще немного протокол... Практическая ценность данного устройства не на высоте (особенно для карписи) - измерение расстояния кратно дециметру, данные о расстоянии до препятствия только применительно к сторонам (левая/правая).
В третьем байте 1-я тетрада признак датчика С, 2-я тетрада - датчик D.
В четвертом байте, соответственно, датчики A и B.
Пятый байт - контрольная сумма.
Все, я с этим парктроником закончил! Теперь бы с авто паркмастер снять.... Вот его точно планирую для бортового компа использовать. oops1, у тебя кажись такая же задача?
да, я тоже парк мастер хотел подключить, а китайский брал для экспериментов.
Но у меня постоянно времени не хватает. вот после выходных уезжаю на 3 недели.
Ноя сомневаюсь что паркмастер будет кардинально отличатся от китайского.