- Registriert
- 08.08.2007
- Beiträge
- 1.949
Hallo,
es gibt ja eine recht umfangreich Arduino Libary für die IR Übertragung. Ich möchte allerdings nicht über eine IR Diode und Empfänger übertragen, sondern über Draht.
Dazu habe ich zwei Arduino Nano miteinander verbunden (+ / - / Datenleitung)
Es werden auch Daten übertragen, aber die "passen" nicht.
Gemessen mit dem Programm "Reveiver Timing Analysis bekomme ich folgende Werte:
13:41:53.713 -> Mark : SampleCount=190 Minimum=32 @13 Maximum=84 @3 Delta=52 Average=41
13:41:53.713 -> ShortSpace: SampleCount=80 Minimum=20 @60 Maximum=576 @54 Delta=556 Average=57
13:41:53.713 -> LongSpace : SampleCount=11 Minimum=1672 @6 Maximum=4504 @0 Delta=2832 Average=1941
13:41:53.713 -> Analysis :
13:41:53.713 -> Average (Mark + ShortSpace)/2=49us Delta (to NEC standard 560)=-511us
13:41:53.713 -> Mark - Average -> MARK_EXCESS_MICROS=-8us
13:41:53.713 ->
Auf dem Sender läuft bei mir folgendes Programm
Auf dem Empfänger dies hier
Was mache ich da falsch?
es gibt ja eine recht umfangreich Arduino Libary für die IR Übertragung. Ich möchte allerdings nicht über eine IR Diode und Empfänger übertragen, sondern über Draht.
Dazu habe ich zwei Arduino Nano miteinander verbunden (+ / - / Datenleitung)
Es werden auch Daten übertragen, aber die "passen" nicht.
Gemessen mit dem Programm "Reveiver Timing Analysis bekomme ich folgende Werte:
13:41:53.713 -> Mark : SampleCount=190 Minimum=32 @13 Maximum=84 @3 Delta=52 Average=41
13:41:53.713 -> ShortSpace: SampleCount=80 Minimum=20 @60 Maximum=576 @54 Delta=556 Average=57
13:41:53.713 -> LongSpace : SampleCount=11 Minimum=1672 @6 Maximum=4504 @0 Delta=2832 Average=1941
13:41:53.713 -> Analysis :
13:41:53.713 -> Average (Mark + ShortSpace)/2=49us Delta (to NEC standard 560)=-511us
13:41:53.713 -> Mark - Average -> MARK_EXCESS_MICROS=-8us
13:41:53.713 ->
Auf dem Sender läuft bei mir folgendes Programm
Code:
/*
* SimpleSender.cpp
*
* Demonstrates sending IR codes in standard format with address and command
* An extended example for sending can be found as SendDemo.
*
* Copyright (C) 2020-2021 Armin Joachimsmeyer
* armin.joachimsmeyer@gmail.com
*
* This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
*
* MIT License
*/
#include <Arduino.h>
/*
* Define macros for input and output pin etc.
*/
//#include "PinDefinitionsAndMore.h"
#define IR_RECEIVE_PIN 2
#define IR_SEND_PIN 3
//#define IR_SEND_PIN 9
#define TONE_PIN 4
#define APPLICATION_PIN 5
#define ALTERNATIVE_IR_FEEDBACK_LED_PIN 6 // E.g. used for examples which use LED_BUILDIN for example output.
#define IR_TIMING_TEST_PIN 7
#include <IRremote.hpp>
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
// Just to know which program is running on my Arduino
Serial.println(F("START " __FILE__ " from " __DATE__ "\r\nUsing library version " VERSION_IRREMOTE));
/*
* The IR library setup. That's all!
*/
IrSender.begin(IR_SEND_PIN, ENABLE_LED_FEEDBACK); // Specify send pin and enable feedback LED at default feedback LED pin
Serial.print(F("Ready to send IR signals at pin "));
Serial.println(IR_SEND_PIN);
}
/*
* Set up the data to be sent.
* For most protocols, the data is build up with a constant 8 (or 16 byte) address
* and a variable 8 bit command.
* There are exceptions like Sony and Denon, which have 5 bit address.
*/
uint16_t sAddress = 0x0102;
uint8_t sCommand = 0x34;
uint8_t sRepeats = 0;
void loop() {
/*
* Print current send values
*/
Serial.println();
Serial.print(F("Send now: address=0x"));
Serial.print(sAddress, HEX);
Serial.print(F(" command=0x"));
Serial.print(sCommand, HEX);
Serial.print(F(" repeats="));
Serial.print(sRepeats);
Serial.println();
Serial.println(F("Send NEC with 16 bit address"));
Serial.flush();
// Results for the first loop to: Protocol=NEC Address=0x102 Command=0x34 Raw-Data=0xCB340102 (32 bits)
IrSender.sendNEC(sAddress, sCommand, sRepeats);
/*
* If you cannot avoid to send a raw value directly like e.g. 0xCB340102 you must use sendNECRaw()
*/
// Serial.println(F("Send NECRaw 0xCB340102"));
// IrSender.sendNECRaw(0xCB340102, sRepeats);
/*
* Increment send values
* Also increment address just for demonstration, which normally makes no sense
*/
/* sAddress += 0x0101;
sCommand += 0x11;
sRepeats++;
// clip repeats at 4
if (sRepeats > 4) {
sRepeats = 4;
}
*/
delay(1000); // delay must be greater than 5 ms (RECORD_GAP_MICROS), otherwise the receiver sees it as one long signal
}
Auf dem Empfänger dies hier
Code:
/*
* ReceiverTimingAnalysis.cpp
*
* This program enables the pin change interrupt at pin 3 and waits for NEC (or other Pulse-Distance-Coding) IR Signal.
* It measures the pulse and pause times of the incoming signal and computes some statistics for it.
*
* Observed values:
* Delta of each signal type is around 50 up to 100 and at low signals up to 200. TSOP is better, especially at low IR signal level.
* VS1838 Mark Excess -50 to +50 us
* TSOP31238 Mark Excess 0 to +50
*
*
* Copyright (C) 2019-2020 Armin Joachimsmeyer
* armin.joachimsmeyer@gmail.com
*
* This file is part of IRMP https://github.com/ukw100/IRMP.
* This file is part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
*
* IRMP is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/gpl.html>.
*
*/
#include <Arduino.h>
#define IR_INPUT_PIN 3
/*
* Helper macro for getting a macro definition as string
*/
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
void measureTimingISR(void);
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
#if defined(__AVR_ATmega32U4__) || defined(SERIAL_USB) || defined(SERIAL_PORT_USBVIRTUAL) || defined(ARDUINO_attiny3217)
delay(4000); // To be able to connect Serial monitor after reset or power up and before first print out. Do not wait for an attached Serial Monitor!
#endif
// Just to know which program is running on my Arduino
Serial.println(F("START " __FILE__ " from " __DATE__));
#if defined(EICRA) && defined(EIFR) && defined(EIMSK)
// enable interrupt on pin3 on both edges for ATmega328
EICRA |= _BV(ISC10);
// clear interrupt bit
EIFR |= 1 << INTF1;
// enable interrupt on next change
EIMSK |= 1 << INT1;
#else
attachInterrupt(digitalPinToInterrupt(IR_INPUT_PIN), measureTimingISR, CHANGE);
#endif
Serial.println(F("Ready to analyze NEC IR signal at pin " STR(IR_INPUT_PIN)));
Serial.println();
}
uint8_t ISREdgeCounter = 0;
volatile uint32_t LastMicros;
struct timingStruct
{
uint16_t minimum;
uint8_t indexOfMinimum;
uint16_t maximum;
uint8_t indexOfMaximum;
uint16_t average;
uint16_t SumForAverage;
uint8_t SampleCount;
// uint8_t LastPrintedCount;
};
struct timingStruct Mark;
struct timingStruct ShortSpace;
struct timingStruct LongSpace;
/*
* Compute minimum, maximum and average
*/
void processTmingValue(struct timingStruct *aTimingStruct, uint16_t aValue)
{
if (aTimingStruct->SampleCount == 0)
{
// initialize values
aTimingStruct->minimum = 0xFFFF;
aTimingStruct->maximum = 0;
aTimingStruct->SumForAverage = 0;
}
if (aTimingStruct->minimum > aValue)
{
aTimingStruct->minimum = aValue;
aTimingStruct->indexOfMinimum = aTimingStruct->SampleCount;
}
if (aTimingStruct->maximum < aValue)
{
aTimingStruct->maximum = aValue;
aTimingStruct->indexOfMaximum = aTimingStruct->SampleCount;
}
aTimingStruct->SampleCount++;
aTimingStruct->SumForAverage += aValue;
aTimingStruct->average = (aTimingStruct->SumForAverage + (aTimingStruct->SampleCount / 2)) / aTimingStruct->SampleCount;
}
void printTimingValues(struct timingStruct *aTimingStruct, const char *aCaption)
{
// if (aTimingStruct->LastPrintedCount != aTimingStruct->SampleCount)
// {
// aTimingStruct->LastPrintedCount = aTimingStruct->SampleCount;
Serial.print(aCaption);
Serial.print(F(": SampleCount="));
Serial.print(aTimingStruct->SampleCount);
Serial.print(F(" Minimum="));
Serial.print(aTimingStruct->minimum);
Serial.print(F(" @"));
Serial.print(aTimingStruct->indexOfMinimum);
Serial.print(F(" Maximum="));
Serial.print(aTimingStruct->maximum);
Serial.print(F(" @"));
Serial.print(aTimingStruct->indexOfMaximum);
Serial.print(F(" Delta="));
Serial.print(aTimingStruct->maximum - aTimingStruct->minimum);
Serial.print(F(" Average="));
Serial.print(aTimingStruct->average);
Serial.println();
// }
}
void loop()
{
if (Mark.SampleCount >= 32)
{
/*
* This check enables statistics for longer protocols like Kaseikyo/Panasonics
*/
#if !defined(ARDUINO_ARCH_MBED)
noInterrupts();
#endif
uint32_t tLastMicros = LastMicros;
#if !defined(ARDUINO_ARCH_MBED)
interrupts();
#endif
uint32_t tMicrosDelta = micros() - tLastMicros;
if (tMicrosDelta > 10000)
{
// NEC signal ended just now
Serial.println();
printTimingValues(&Mark, "Mark ");
printTimingValues(&ShortSpace, "ShortSpace");
printTimingValues(&LongSpace, "LongSpace ");
/*
* Print analysis of mark and short spaces
*/
Serial.println(F("Analysis :"));
Serial.print(F(" Average (Mark + ShortSpace)/2="));
int16_t MarkAndShortSpaceAverage = (Mark.average + ShortSpace.average) / 2;
Serial.print(MarkAndShortSpaceAverage);
Serial.print(F("us Delta (to NEC standard 560)="));
Serial.print(MarkAndShortSpaceAverage - 560);
Serial.print(F("us\r\n Mark - Average -> MARK_EXCESS_MICROS="));
Serial.print((int16_t) Mark.average - MarkAndShortSpaceAverage);
Serial.print(F("us"));
Serial.println();
Serial.println();
Mark.SampleCount = 0; // used as flag for not printing the results more than once
}
}
}
/*
* The interrupt handler.
* Just add to the appropriate timing structure.
*/
#if defined(ESP8266)
void ICACHE_RAM_ATTR measureTimingISR()
#elif defined(ESP32)
void IRAM_ATTR measureTimingISR()
#else
# if defined(EICRA) && defined(EIFR) && defined(EIMSK)
ISR(INT1_vect)
# else
void measureTimingISR()
# endif
#endif
{
uint32_t tMicros = micros();
uint32_t tMicrosDelta = tMicros - LastMicros;
LastMicros = tMicros;
/*
* read level and give feedback
*/
uint8_t tInputLevel = digitalRead(IR_INPUT_PIN);
digitalWrite(LED_BUILTIN, !tInputLevel);
if (tMicrosDelta > 10000)
{
// gap > 10 ms detected, reset counter to first detected edge and initialize timing structures
ISREdgeCounter = 1;
LongSpace.SampleCount = 0;
ShortSpace.SampleCount = 0;
Mark.SampleCount = 0;
}
else
{
ISREdgeCounter++;
}
/*
* Skip header mark and space and first bit mark and space
*/
if (ISREdgeCounter > 4)
{
if (tInputLevel != LOW)
{
// Mark ended
processTmingValue(&Mark, tMicrosDelta);
// Serial.print('M');
}
else
{
// Space ended
if (tMicrosDelta > 1000)
{
// long space - logical 1
processTmingValue(&LongSpace, tMicrosDelta);
Serial.print('1');
}
else
{
// short space - logical 0
processTmingValue(&ShortSpace, tMicrosDelta);
Serial.print('0');
}
}
}
}
Was mache ich da falsch?