Извиняюсь за отсутствие у меня дочка родилась не до патронника
.
Я поправил плагин центрифуги. Я не довел до конца. сделал чтобы все работало.
Патронник я брал чтобы разобратся, использовать его не планирую. у меня в машине стоит Паркмастер хочу его прикрутить.
Чуть позже выложу сырцы плагина и последний работающий скетч ардуино .
Мои поздравления!!! Пусть дочь красавицей растет!!!
Поздравляю!!! Пусть растет здоровой и счастливой!
Могу оптимизировать скетчь, но без плагина и парктроника ни как
Парктроник закажу, а вот плагин с тебя.
Последний раз редактировалось Chip; 03.03.2011 в 22:49.
Спасибо , за поздравления
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 снимая сигнал через звуковую плату. Вот что получилось:
еще, крупнее-
и еще крупнее-
Возникает вопрос-а справится ли ардуино для считывания таких коротких импульсов, а конкретно скетч oops1?
0,5 мс не такой уж и короткий сигнал.
1 такт при кварце 16мГц равен 62 наносекунам.
Для лучшей точности я бы использовал таймер1 на прямую без библиотеки. Настроил его бы без пред делителя , его максимальное время получится 4мс, надеюсь у парктроника нет импульсов длинеее 4 мс , но если что всегда можно будет увеличить длительность отсчета до требуемой величины
Последний раз редактировалось Chip; 03.04.2011 в 03:12.
В общем скетч на основе листинга oops1 для распознавания импульсов работает. Только я снимаю длительности "ноля". Так удобнее определить начала пакета.
Но, как оказалось, это не самая главная проблема. Проблема в том что я не могу "вычислить" протокол - не очень как то понятно "Ху ис ху". Понятно что все данные укладываются в один пакет, пакет всегда заканчивается "1". Где в нем данные расстояния, где признак датчика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 --
Ни у кого мыслей не появилось?...
Эту тему просматривают: 2 (пользователей: 0 , гостей: 2)