Цитата:
Сообщение от Bulatovor
как самое простое ногу от ИК приемника повесить на пин 2, а от детектора нуля перенести на 3
|
Я использую библиотеку IRemote для работы с ИК и в ней почему-то 3й пин жестко зашит для передачи ИК сигнала. Поэтому на 3м пине у меня висит ИК диод. Я, конечно, попробую поправить библиотеку, чтобы высвободить 3й пин и настроить прерывание. Или есть какая-то библиотека получше для работы с ИК?
Цитата:
Сообщение от Bulatovor
Мигать свет будет тока при обработки команды с пульта.
|
Хотелось бы, чтобы свет вообще не мигал из-за ИК приемника) По крайней мере при считывании температуры этого удалось добиться.
Цитата:
Сообщение от Bulatovor
А вообще лучше код выложить -не должен он из-за loop мигать -ведь это прерывание. Скорее считывать с приемника некорректно должен из-за частых прерываний
|
У меня в коде всего понапичкано. Чтение команд с WiFi, управление телеком, светом. Постарался вырезать лишнее, чтобы не мешало. Но, могу и весь код скинуть. Когда комментирую строчку
readDataFromIR();, свет перестает мигать.
PHP код:
#include <CyberLib.h> //Библиотека от Cyber-Place.ru
#include <IRremote.h>
#include <OneWire.h>
#include <MsTimer2.h>
#define RCNL F("\r\n")
#define NL '\n'
#define DIMMER_CP_DEFAULT 1000
//#define DEBUG
#ifdef DEBUG
#define DEBUG_BAUD 9600
#define DEBUG_RX 8
#define DEBUG_TX 9
#include "SoftwareSerial.h"
#endif
//SoftwareSerial debugSerial (DEBUG_RX,DEBUG_TX); // RX, TX
const int wifiPin = 4;
const int relayPin = 10;
const int ledPin = 13;
const int tempPin = 5;
const int irInPin = 12;
// Hardcoded in IRemote
//const int irOutPin = 3;
const int dimmerInPin = 2;
const int dimmerOutPin = 6;
IRrecv irrecv(irInPin);
IRsend irsend;
OneWire tempSensor(tempPin);
boolean lightEnabled = false;
boolean tvEnabled = false;
boolean tvBrowseChannels = false;
long tvBrowseTime = 0;
float currentTemp = 0;
long timeLastCheck;
bool checkEnabled = true;
volatile uint8_t tic, dimmerValue = 255, dimmerNewValue = 255;
uint8_t data;
int dimmerChangingPeriod = DIMMER_CP_DEFAULT;
void setup() {
D4_Out;
D4_High;
D10_Out;
D10_High;
D13_Out;
D6_Out;
D6_Low;
D2_In;
attachInterrupt(0, detect_up, LOW); // настроить срабатывание прерывания interrupt0 на pin 2 на низкий уровень
StartTimer1(halfcycle, 40); //время для одного разряда ШИМ
StopTimer1();
MsTimer2::set(2000, readDataFromTempSensor); // установка таймера на 2 сек. для изм. температуры
MsTimer2::start();
#ifdef DEBUG
debugSerial.begin(DEBUG_BAUD);
#endif
irrecv.enableIRIn();
debugPrintln(F("Arduino started"));
printFreeRam();
}
void loop() {
updateDimmerLightness();
readDataFromIR();
}
/* Общие методы - Начало */
void printFreeRam() {
String message = F("freeRam=");
message += String(freeRam());
debugPrintln(message);
}
int freeRam () {
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
void debugPrint(String str) {
#ifdef DEBUG
debugSerial.print(str);
#endif
}
void debugPrintln(String str) {
#ifdef DEBUG
debugSerial.println(str);
#endif;
}
/* Общие методы - Конец */
/* Методы для работы с датчиком темперауры - Начало */
void readDataFromTempSensor() {
byte addr[8];
byte present = 0;
byte type_s, dat;
byte data[12];
if (tempSensor.search(addr) && OneWire::crc8(addr, 7) == addr[7]) {
switch (addr[0]) {
case 0x10:
//WIFI_SERIAL.println(" Chip = DS18S20");
type_s = 1;
break;
case 0x28:
//WIFI_SERIAL.println(" Chip = DS18B20");
type_s = 0;
break;
case 0x22:
//WIFI_SERIAL.println(" Chip = DS1822");
type_s = 0;
break;
default:
//WIFI_SERIAL.println("Device not detected");
break;
}
tempSensor.reset();
tempSensor.select(addr);
tempSensor.write(0x44, 1);
dat = tempSensor.read();
while(!dat) {
dat = tempSensor.read();
}
present = tempSensor.reset();
tempSensor.select(addr);
tempSensor.write(0xBE);
for (int i = 0; i < 9; i++) {
data[i] = tempSensor.read();
}
int16_t raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3;
if (data[7] == 0x10) {
raw = (raw & 0xFFF0) + 12 - data[6];
}
}
else {
byte cfg = (data[4] & 0x60);
if (cfg == 0x00) raw = raw & ~7;
else if (cfg == 0x20) raw = raw & ~3;
else if (cfg == 0x40) raw = raw & ~1;
}
currentTemp = (float)raw / 16.0;
}
}
/* Методы для работы с датчиком темперауры - Конец */
/* Методы для работы с IR - Начало */
void readDataFromIR() {
decode_results results;
if (irrecv.decode(&results)) {
if (results.value == 0x20DF10EF) {
//toggleLightState(true);
}
irrecv.resume();
}
}
/* Методы для работы с IR - Конец */
/* Методы для управления светом через диммер - Начало */
void halfcycle() //прерывания таймера
{
tic++; //счетчик
if (dimmerValue < tic ) D6_High; //управляем выходом
}
void detect_up() // обработка внешнего прерывания. Сработает по переднему фронту
{
tic = 0; //обнулить счетчик
ResumeTimer1(); //запустить таймер
attachInterrupt(0, detect_down, HIGH); //перепрограммировать прерывание на другой обработчик
}
void detect_down() // обработка внешнего прерывания. Сработает по заднему фронту
{
StopTimer1(); //остановить таймер
D6_Low; //логический ноль на выходы
tic = 0; //обнулить счетчик
attachInterrupt(0, detect_up, LOW); //перепрограммировать прерывание на другой обработчик
}
void updateDimmerLightness() {
if (dimmerValue < dimmerNewValue) {
int changingDelay = dimmerChangingPeriod / (dimmerNewValue - dimmerValue);
for (int i = dimmerValue; i <= dimmerNewValue; i++) {
dimmerValue = i;
delay_ms(changingDelay);
}
dimmerChangingPeriod = DIMMER_CP_DEFAULT;
}
else if (dimmerValue > dimmerNewValue) {
int changingDelay = dimmerChangingPeriod / (dimmerValue - dimmerNewValue);
for (int i = dimmerValue; i >= dimmerNewValue; i--) {
dimmerValue = i;
delay_ms(changingDelay);
}
dimmerChangingPeriod = DIMMER_CP_DEFAULT;
}
}
/* Методы для управления светом через диммер - Конец */