Спасибо , за поздравления
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% и более.





Ответить с цитированием
