Приемник 433MHz +ATTINY13 и библиотека RemoteSwitch
- Войдите на сайт для отправки комментариев
Здравствуйте!Нужна помощь знающих людей.Делаю автоматику для откатных ворот и вот столкнулся с необходимостью дистанционного управления приводом.В качестве пульта использую связку Attiny13 и передатчик FS1000A, скетч нашел в сети и подправил.На пульте только одна кнопка,при нажатии один раз отправляет код на приемник.При помощи библиотеки RemoteSwitch и примера Show_received_code.ino читаю код пульта:
Received 1394001 / 24bit Protocol: 1
.Отладку приемника делал на UNO ,но для одной функции думаю что ее применение излишне.В наличии есть некоторое количество ATTINY13. В сети по ссылке https://github-com.translate.goog/DROID8622/ATtiny13-433MHz-Receiver-Transmitter?_x_tr_sl=auto&_x_tr_tl=ru&_x_tr_hl=ru&_x_tr_pto=op нашел пример работы приемника и ATTINY13, но в описании скетча ATTINY13-433MHzRemoteSwitch.ino указан протокол работы 12 bit:
Protocol used is known as protocol 12 from RCSwitch library.
{ 320, { 36, 1 }, { 1, 2 }, { 2, 1 }, true }
( 12 bits, pulselength is 320 microseconds , "1" is 640 low / 320 high , "0" is 640 high / 320 low, pilot period is 11520 (320*36).
PROTOCOL is "inverted".
Но пульт передает 24 bit. Возможно ли изменить протокол в скетче приемника на 24 bit?Сам додуматься не могу.Прошу помочь.
Код передатчика
Received 1394001 / 24bit Protocol: 1 data bits of pulse train duration: 38648 proposed protocol: { 399, { 1, 30 }, { 1, 3 }, { 3, 1 }, false } ==== first level down 12084 756 1172 436 1156 432 1168 1200 396 420 1180 1196 404 412 1188 1192 408 408 1188 1196 400 412 1188 416 1180 416 1180 1200 400 408 1192 1180 416 404 1188 1184 412 400 1196 1180 416 400 1192 404 1188 408 1184 1192 404 408 ====Ну это понятно.
void grab() { rxstate = digitalRead(rxPin); if (rxstate == HIGH) lolen = micros() - prevtime; else hilen = micros() - prevtime; prevtime = micros(); if (rxstate == LOW) { if (CheckValue(320, hilen) && CheckValue(640, lolen)) { // valid 1 cameCode = (cameCode << 1) | 1; cameCounter++; } else if (CheckValue(640, hilen) && CheckValue(320, lolen)) { // valid 0 cameCode = (cameCode << 1) | 0; cameCounter++; } else cameCounter = 0; } else if (lolen > 1000 && (cameCounter == 12 || cameCounter == 13) && ((cameCode & 0xfff) != 0xfff)) { lastCode = cameCode & 0xfff; cameCounter = 0; cameCode = 0; } }Что здесь исправить?
Что здесь исправить?
многое. Длину кода, маску, размерность переменной cameCode...
if (rxstate == LOW) { 10 if (CheckValue(320, hilen) && CheckValue(640, lolen)) { 11 // valid 1 12 cameCode = (cameCode << 1) | 1; 13 cameCounter++; 14 } 15 else if (CheckValue(640, hilen) && CheckValue(320, lolen)) { 16 // valid 0 17 cameCode = (cameCode << 1) | 0; 18 cameCounter++; здесь как я понимаю прописываются тайминги.{ 399, { 1, 30 }, { 1, 3 }, { 3, 1 }, false } это маска,да?переменная cameCode... должна быть long.
переменная cameCode... должна быть long.
да. А вот все что выше - ерунда, не имеющая отношения к делу.
Имеется такой код передатчика
#include <avr/io.h> #define txPin PB0 #define LED PB2 #define buttonPin PB1 volatile uint8_t int0Flag = false; void setup() { pinMode(txPin, OUTPUT); pinMode(buttonPin, INPUT); pinMode(LED, OUTPUT); attachInterrupt(0, flag, FALLING); } void loop() { if (int0Flag == true) { delay(20); //задержка для защиты от дребезга PORTB |= (1 << LED); // HIGH SendCame4(2211); delay(20); // Задержка 50 мс (дребезг контактов) PORTB &= ~(1 << LED); // LOW while (digitalRead(buttonPin)) { delay(200); } int0Flag = false; } } void SendCame4(long Code) { noInterrupts(); for (int j = 0; j < 10; j++) { // посылку посылаем 10 раза подряд. // время стартового импульса digitalWrite(txPin, HIGH); delayMicroseconds(320); digitalWrite(txPin, LOW); for (int i = 12; i > 0; i--) { byte b = bitRead(Code, i - 1); // побитово перебираем и посылаем код if (b) { digitalWrite(txPin, LOW); // 1 delayMicroseconds(640); digitalWrite(txPin, HIGH); delayMicroseconds(320); } else { digitalWrite(txPin, LOW); // 0 delayMicroseconds(320); digitalWrite(txPin, HIGH); delayMicroseconds(640); } } digitalWrite(txPin, LOW); delayMicroseconds(11520); } interrupts(); } void flag() { int0Flag = true; }Криво но работает,переделаю.Передает код 2211 , 12bit.
Код приемника
#define rxPin 2 //receiver #define ledPin 4 // LED or relay #define MAX_DELTA 200 // impulse lenght may vary of battery and so on, max deviation is 200 volatile static int lastCode = 0; volatile unsigned long prevtime; volatile unsigned int lolen, hilen, rxstate; volatile static byte cameCounter = 0; // count of bits stored volatile static int cameCode = 0; // code itself boolean CheckValue(unsigned int base, unsigned int value) { return ((value == base) || ((value > base) && ((value - base) < MAX_DELTA)) || ((value < base) && ((base - value) < MAX_DELTA))); } void setup() { pinMode(rxPin, INPUT); pinMode(ledPin, OUTPUT); attachInterrupt(INT0, grab, CHANGE); //INT0 PB1 hardware interrupt //interrupts(); } void loop() { if (lastCode == 2211) { digitalWrite(ledPin, HIGH); delay(20); digitalWrite(ledPin, LOW); } lastCode = 0; } void grab() { rxstate = digitalRead(rxPin); if (rxstate == HIGH) lolen = micros() - prevtime; else hilen = micros() - prevtime; prevtime = micros(); if (rxstate == LOW) { if (CheckValue(320, hilen) && CheckValue(640, lolen)) { // valid 1 cameCode = (cameCode << 1) | 1; cameCounter++; } else if (CheckValue(640, hilen) && CheckValue(320, lolen)) { // valid 0 cameCode = (cameCode << 1) | 0; cameCounter++; } else cameCounter = 0; } else if (lolen > 1000 && (cameCounter == 12 || cameCounter == 13)) { lastCode = cameCode ; cameCounter = 0; cameCode = 0; } }Работает на UNO и attyny13(с небольшими изменениями). Задача такая : после принятия кода один раз моргнуть светодиодом. Но моргает иногда несколько раз.
В программировании как конь в воде, но пытаюсь разбираться.
как конь в воде
Это как ???
Как дельфин,только на оборот. Самостоятельно изучаю, книги, ютуб,смотрю примеры кода,пробую.
Ну кони то плавают, хоть как то. В отличие от коров.)
У меня объект был с дельфинами. Для уничтожения пловцов. После него я дельфинов боялся офигенно как.(
Ну кони то плавают, хоть как то. В отличие от коров.)
У меня объект был с дельфинами. Для уничтожения пловцов. После него я дельфинов боялся офигенно как.(
Коровы нормально плавают.Я деревенский и видел как одна буренка ставок пересекала.
Хе-хе. Ну, значит это мой пробел.)
Вот скетч для привода откатных ворот:
// Распиновка Аттини 2313 #include <util/delay.h> #define LED_FLASH_GREEN 10 // светодиод ----- PORTPB1 #define Swihc_Open_PIN 0 // концевик "Открыто" #define Swihc_Close_PIN 1 // концевик "Закрыто" #define Fotoelement_PIN 5 // вход ИК датчика препятствия #define Button_State_PIN 7 // кнопка переключения режимов "Открыть-Стоп-Закрыть" #define Close_Rele_Pin 8 //выход на реле ЗАКРЫТЬ ---- PORTPD6 #define Open_Rele_Pin 12 //выход на реле ОТКРЫТЬ ---- PORTPB3 #define Power_TRANS_PIN 13 // выход на реле трансформатора питания привода мотора ---- PORTPB4 #define Rele_Unbloking_PIN 14 //выход на реле механизма блокировки движения ворот ---- PORTPB5 #define MOTOR_Pin_PWM 11 // пин выхода ШИМ на мотор ----- PORTPB2 #define Unbloking_Taim (3*1000) // время работы Rele_Unbloking #define LED_FLASH_RED 9 // мигалка ----- PORTPB0 #define BLINK_TIME 150 // скорость моргания красного светодиода #define DEBOUNCE 100 // задержка для антидребезга кнопки #define MOTOR_TIMEOUT (45*1000) // Время допустимой работы мотора в миллисекундах boolean reverse_motor; //переменная для реверса boolean Bloking ; //переменная разблокировки ворот unsigned long StartTimer; // счетчик времени для плавного пуска int StartTimeStep = 1; // Интервал изменения мощности двигателя, в мс int StartPowerStep = 12; // Один шаг изменения мощности двигателя int MotorPower ; // Мощность двигателя enum {STOP, CLOSE, CLOSED, OPEN, OPENED }; // возможные состояния системы byte state; // текущее состояние системы byte lastDir; // предыдущее направление движения ворот byte nextDir; // следующее направление движения ворот unsigned long startTime = 0; //время начала движения long previousMillisA = 0; //переменная времени byte valA; //переменная счетчик void setup() { // put your setup code here, to run once: pinMode (LED_FLASH_GREEN, OUTPUT); pinMode (LED_FLASH_RED, OUTPUT); pinMode (MOTOR_Pin_PWM, OUTPUT); pinMode(Swihc_Open_PIN, INPUT); pinMode(Swihc_Close_PIN, INPUT); pinMode(Fotoelement_PIN, INPUT); pinMode(Button_State_PIN, INPUT); pinMode(Close_Rele_Pin, OUTPUT); pinMode(Open_Rele_Pin, OUTPUT); pinMode(Power_TRANS_PIN, OUTPUT); pinMode(Rele_Unbloking_PIN, OUTPUT); state = STOP; // исходное состояние после включения питания lastDir = CLOSE; //последнее направление движения ворот nextDir = OPEN; // следующее направление движения ворот MotorPower = 0; // Начальная мощность мотора } void loop() { readButton(); // опрос кнопки checkSwitches(); // опрос концевиков, при коллизиях подавляет команду от кнопки ledsManager(); // световая индикация motor(); // управление двигателем reverse(); //реверс после сработки фотоэлемента checkTimeout(); //таймаут работы по времени } void checkTimeout() { if ((state == OPEN || state == CLOSE) && ( (millis() - startTime) > MOTOR_TIMEOUT)) { state = STOP; lastDir = state; // я бы добавил состояние "заклинило" } } void readButton() { static bool butt_flag = 0; static long past = 0; if ((millis() - past) < 20 ) return; if (digitalRead(Button_State_PIN) ) // если нажата кнопка { if (butt_flag) return; butt_flag = true; past = millis(); if (state == STOP && lastDir == CLOSE ) // даем команду на открытие { state = OPEN; startTime = millis(); MotorPower = 120; // Начальная мощность мотора } else if (state == STOP && lastDir == OPEN) // даем команду на закрытие { state = CLOSE; startTime = millis(); MotorPower = 120; // Начальная мощность мотора } else if (state == OPEN || state == CLOSE ) // даем команду на остановку { lastDir = state; state = STOP; startTime = 0; } else if (state == OPENED && nextDir == CLOSE) { nextDir = CLOSE; state = nextDir; startTime = millis(); MotorPower = 120; // Начальная мощность мотора } else if (state == CLOSED && nextDir == OPEN) { nextDir = OPEN; state = nextDir; startTime = millis(); MotorPower = 120; // Начальная мощность мотора } } else { if (!butt_flag) return; butt_flag = false; past = millis(); } } void checkSwitches() { if (( digitalRead(Swihc_Open_PIN)) && state == OPEN) // полностью открытые ворота { nextDir = CLOSE; state = OPENED; reverse_motor = false; } else if (( digitalRead(Swihc_Close_PIN)) && state == CLOSE) // полностью закрытые ворота { nextDir = OPEN; state = CLOSED; Bloking = true; } } void motor() { if (state == STOP) { MotorPower = 0; // Начальная мощность мотора analogWrite (MOTOR_Pin_PWM, MotorPower); // Выключаем ШИМ PORTB &= ~(1 << 4);//Power_TRANS_PIN LOW PORTB &= ~(1 << 3); // Open_Rele_Pin 12 LOW PORTD &= ~(1 << 6); // Close_Rele_Pin 8 LOW PORTB &= ~(1 << 5);// Rele_Unbloking_PIN LOW } else if (state == OPEN) { if (Bloking == true && ( digitalRead(Swihc_Close_PIN)) && ( (millis() - startTime) <= Unbloking_Taim)) { PORTB |= (1 << 5);// Rele_Unbloking_PIN HIGH } else if (Bloking == true && ( (millis() - startTime) > Unbloking_Taim )) { PORTB &= ~(1 << 5);// Rele_Unbloking_PIN LOW Bloking = false; } PORTB |= (1 << 4);//Power_TRANS_PIN HIGH PORTB |= (1 << 3); // Open_Rele_Pin 12 HIGH PORTD &= ~(1 << 6); // Close_Rele_Pin 8 LOW motorForvard(); } else if (state == CLOSE) { if (digitalRead(Fotoelement_PIN) ) { PORTB |= (1 << 4);//Power_TRANS_PIN HIGH PORTD |= (1 << 6); // Close_Rele_Pin 8 HIGH PORTB &= ~(1 << 3); // Open_Rele_Pin 12 LOW motorForvard(); } else { state = STOP; reverse_motor = true; } } else if (state == OPENED) { MotorPower = 0; // Начальная мощность мотора analogWrite (MOTOR_Pin_PWM, MotorPower); // Выключаем ШИМ PORTB &= ~(1 << 4);//Power_TRANS_PIN LOW PORTB &= ~(1 << 5);// Rele_Unbloking_PIN LOW PORTB &= ~(1 << 3); // Open_Rele_Pin 12 PORTD &= ~(1 << 6); // Close_Rele_Pin 8 } else if (state == CLOSED) { MotorPower = 0; // Начальная мощность мотора analogWrite (MOTOR_Pin_PWM, MotorPower); // Выключаем ШИМ PORTB &= ~(1 << 4);//Power_TRANS_PIN LOW PORTB &= ~(1 << 5);// Rele_Unbloking_PIN LOW PORTB &= ~(1 << 3); // Open_Rele_Pin 12 PORTD &= ~(1 << 6); // Close_Rele_Pin 8 } //delay(DEBOUNCE); // простейший антидребезг кнопки _delay_ms(DEBOUNCE); } void ledsManager() { boolean ledState; static unsigned long timestamp = millis(); if (state == STOP ) { //digitalWrite(LED_FLASH_RED, HIGH); PORTB |= (1 << 0); } else if (state == CLOSED || state == OPENED) { //digitalWrite(LED_FLASH_GREEN, HIGH); //digitalWrite(LED_FLASH_RED, LOW); PORTB |= (1 << 1); PORTB &= ~(1 << 0); } else { if (millis() - timestamp > BLINK_TIME) { ledState = LOW; timestamp = millis(); } else ledState = HIGH; //digitalWrite(LED_FLASH_GREEN, LOW); PORTB &= ~(1 << 1); digitalWrite(LED_FLASH_RED, ledState); } } void reverse() { if ( reverse_motor == true && state == STOP) { if (millis() - previousMillisA > 1000) { previousMillisA = millis(); state = STOP; // работает счет valA++; } if (valA >= 4) //кол-во секунд((millis() -previousMillisA >1000) при достижении этого значения , мотор включается { nextDir = OPEN; state = nextDir; startTime = millis(); MotorPower = 120; motorForvard(); valA = 0; } } } void motorForvard() { if ((state == OPEN && MotorPower >= 120) || (state == CLOSE && MotorPower >= 120 ) ) if (MotorPower < 255) { if ((millis() - StartTimer) >= StartTimeStep) // Проверяем, сколько прошло с последнего изменения скорости // если больше, чем заданный интервал – увеличим скорость еще на один шаг { MotorPower += StartPowerStep; // увеличение скорости analogWrite (MOTOR_Pin_PWM, MotorPower); // На выводе управляющий сигнал с новой скоростью StartTimer = millis(); // Начало нового шага } } }Был найден в сети. Примерно 70% переписал под себя.Много пришлось познать для этого, тяжело но интересно.
Даже не смотрел. Но. Я тут у себя делал фонарь с RC switch - там tiny45 едва хватило. Выебоны начинались из за нехватки RAM... Понятно, что можно поизгаляться, но только заради чего.
Код приемника выше,он на тиньке13 работает.
Скетч использует 774 байт (75%) памяти устройства. Всего доступно 1024 байт.
. Изначально было две команды.Один раз нажал кнопочку приходит код - ВКЛ,второй раз- ВЫКЛ.Как триггер.А мне нужно чтобы по нажатию кнопки пульта на выходе приемника однократно появлялась лог.1 и моргал светодиод. А оно моргает по несколько раз.
Я ж говорю. Дело не во Flash, дело в RAM.
Глобальные переменные используют 21 байт (32%) динамической памяти, оставляя 43 байт для локальных переменных. Максимум: 64 байт.
Всем привет. Нужна помощь .
Нужен считать коды с шлагбаума
doorhan .
И сделать чтоб его снова отправить .чтоб шлагбаум открывался. .
Есть какие ворианты. ?
Имеется передатчик и приемник от сигнализации СтарЛайн ну и Ардуино нано )
sanekovich шел бы ты отсюда, дядя
В восьмом сообщении "Код приемника". В 26-й строке добавить
"cameCode = 0;".