The circuit looks ok. You might want to test the resistor with your meter to make sure it is 4.7K.
Instead of the blanket, you might try a pulldown resistor on the transistor base.
The other possibility would be to cover up the second LED with black tape so the only one you're measuring is the one you tapped into before that gave you the good results.
When I tested my circuit before, I just tested the output on my scope, but didn't actually test it feeding my Arduino. So this morning I set it up again, and fed it into my ESP8266, which is the closest MCU I have to the Uno R4. It read ok, but I found that the duty cycle varied tremendously depending on how far the remote was from the IRLED. I could get on/off cycles of 4-22 far away, or 13-13 close in.
But the one thing that was constant was the total cycle time, which for my 38KHz remote is about 26us:
So I changed my code to only look at the total cycle time:
// capture incoming IR - Nano R4
// total cycle time
#define IR_PIN A1
unsigned long durations[300];
unsigned long prevMicros;
unsigned long newMicros;
int count = 0;
bool endit = false;
void setup() {
pinMode(IR_PIN, INPUT);
Serial.begin(57600);
}
void loop() {
count = 0;
endit = false;
while (digitalRead(IR_PIN) == HIGH); // Wait for signal to go LOW
prevMicros = micros();
while ((count < 300) && (endit == false)) {
newMicros = micros();
durations[count] = newMicros - prevMicros;
count++;
prevMicros = newMicros;
while (digitalRead(IR_PIN) == LOW);
while (digitalRead(IR_PIN) == HIGH) {
if ((micros() - prevMicros) > 2000000) {
endit = true;
break;
}
}
}
Serial.println("\nSignal:");
for (int i = 1; i < count; i++) {
Serial.print(durations[i]);
Serial.print(" ");
if ((i & 31) == 31) Serial.println();
}
Serial.println("\n---");
delay(1000); // Small pause between readings
}
This should still work with the post 200 values. There will be one shorter cycle time that represents a zero bit, and a longer cycle time that represents a one bit. So instead of getting
#include <LiquidCrystal_I2C.h>
#include "Arduino_LED_Matrix.h"
#define IR_PIN A1
LiquidCrystal_I2C lcd(0x27, 16, 2);
unsigned long durations[300];
unsigned long prevMicros;
unsigned long newMicros;
int count = 0;
bool endit = false;
void decodeMessage() {
bool recording = false;
unsigned long message = 0;
for (int i = 0; i < 300 - 1; i++) {
int d = durations[i];
// Look for start and end pulses > 1000 µs
if (d > 1000) {
if (!recording) {
recording = true; // Start of message
message = 0;
continue;
} else {
break; // End of message
}
}
if (recording) {
if (i + 1 >= 300) break;
int pulse1 = durations[i];
int pulse2 = durations[i + 1];
if (pulse1 >= 3 && pulse1 <= 9) {
message <<= 1;
if (pulse2 >= 35 && pulse2 <= 41) {
message |= 1;
} else if (pulse2 >= 18 && pulse2 <= 26) {
}
}
}
}
message = message >>1 ;
Serial.print("Raw binary value: ");
Serial.println(message);
unsigned int deviceID = (message >> 5) & 0x7FFF; // 0x7FFF = 15 bits mask (0111 1111 1111 1111)
if(deviceID > 10000) {
Serial.print("ID: ");
Serial.println(deviceID);
lcd.setCursor(0, 0);
lcd.print(deviceID);
}
}
void setup() {
pinMode(IR_PIN, INPUT);
Serial.begin(57600);
lcd.init(); // initialize the lcd
lcd.backlight();
}
void loop() {
count = 0;
endit = false;
while (digitalRead(IR_PIN) == HIGH); // Wait for signal to go LOW
prevMicros = micros();
while ((count < 300) && (endit == false)) {
newMicros = micros();
durations[count++] = newMicros - prevMicros;
prevMicros = newMicros;
while (digitalRead(IR_PIN) == LOW);
newMicros = micros();
durations[count++] = newMicros - prevMicros;
prevMicros = newMicros;
while (digitalRead(IR_PIN) == HIGH) {
if ((micros() - prevMicros) > 2000000) {
endit = true;
break;
}
}
}
Serial.println("Signal:");
for (int i = 1; i < count; i++) {
Serial.print(durations[i]);
Serial.print(" ");
}
decodeMessage();
Serial.println("\n---");
delay(1000); // Small pause between readings
}
The decode message part was for the signal i had at the #200 post, but i need to have a different way to decode it, since now it depends on the distance that i'am at, but it depending on where i'am at, IT WORKS.
Since you had no success with the IRRemote library
I'm not sure where else to go with this since my hunch I suppose was incorrect and you'll have to press on with your current strategy. I guess if it was me, I would try that other IR library I mentioned that claims to read 50 (as opposed to 17) IR protocols but that's just how I would approach it from my way (non professional) of doing things.
Hopefully the additional details of what you're trying to accomplish helps the other helpers here toward your goal. At least for me it always helps to be able to form a mental image of what is being built overall, although in your case, sorry I can't be more help as I simply don't know.
Don't worry, i'm actually already very close to the answer, so as i said in post #390 i have already a way that work for receiving the signal, the only problem i have now is how to code a decoder, because depending on the distance i'am at with the remote controller i have low's and high with different microseconds, here is the code i use for decoding now :
#include <LiquidCrystal_I2C.h>
#include "Arduino_LED_Matrix.h"
#define IR_PIN A1
LiquidCrystal_I2C lcd(0x27, 16, 2);
unsigned long durations[45];
unsigned long prevMicros;
unsigned long newMicros;
int count = 0;
bool endit = false;
bool readstate = false;
void decodeMessage() {
bool recording = false;
unsigned long message = 0;
for (int i = 0; i < 45 - 1; i++) {
int d = durations[i];
// Look for start and end pulses > 1000 µs
recording = true; // Start of message
if (recording) {
if (i + 1 >= 45) break;
int pulse1 = durations[i];
int pulse2 = durations[i + 1];
if(pulse1 > 13 && durations[i-1]>=14) {
readstate = true ;
}
if (pulse1 >= 3 && pulse1 <= 13) {
message <<= 1;
if (pulse2 >= 29 && pulse2 <= 41) {
message |= 1;
} else if (pulse2 >= 14 && pulse2 <= 25) {
}
}
if(durations[i]>1000) {
readstate = true ;
}
}
}
if(readstate == false) {
Serial.println(" ");Serial.print("Raw binary value: ");Serial.println(message, BIN);
if (message <= 5) {
lcd.clear() ;
lcd.setCursor(0, 0);
lcd.print("Wrong distance");
lcd.setCursor(0 ,3);
lcd.print("No Signal");
} else {
unsigned int Buttonread = (message>> 20);
unsigned int deviceID = (message >> 5) & 0x7FFF; // 0x7FFF = 15 bits mask (00 111 1111 1111 1111)
lcd.clear() ;
Serial.println(" ");Serial.print("ID: ");Serial.println(deviceID);
Serial.print(Buttonread);
lcd.setCursor(0, 0);
lcd.print(deviceID);
if (Buttonread == 3) {
lcd.setCursor(0, 3);
lcd.print("Button 1");
}else if (Buttonread == 0) {
lcd.setCursor(0, 3);
lcd.print("Button 2");
}
}
}else if (readstate == true) {
readstate = false ;
lcd.clear() ;
lcd.setCursor(0, 0);
lcd.print("Wrong detection");
}
}
void setup() {
pinMode(IR_PIN, INPUT);
Serial.begin(57600);
lcd.init(); // initialize the lcd
lcd.backlight();
}
void loop() {
count = 0;
endit = false;
while (digitalRead(IR_PIN) == HIGH); // Wait for signal to go LOW
prevMicros = micros();
while ((count < 300) && (endit == false)) {
newMicros = micros();
durations[count++] = newMicros - prevMicros;
prevMicros = newMicros;
while (digitalRead(IR_PIN) == LOW);
newMicros = micros();
durations[count++] = newMicros - prevMicros;
prevMicros = newMicros;
while (digitalRead(IR_PIN) == HIGH) {
if ((micros() - prevMicros) > 2000000) {
endit = true;
break;
}
}
}
Serial.println("Signal:");
for (int i = 1; i < count; i++) {
Serial.print(durations[i]);
Serial.print(" ");
}
decodeMessage();
Serial.println("\n---");
delay(1000); // Small pause between readings
}
But currently i have a limited band of values where i can decipher the message with this code, since the called (pulse1) which is the equivalent of the 3's and 4's of the post #200 vary a lot, like sometimes it goes up to 20, which doesn't decode well since the pulse2 (the one that is supposed to be low ~22 on post #200 ) sometimes is lower than the 1, i don't know how to improve my code rn, but it works sometimes.
It wasn't clear what change you made to the circuit to get this, but it appears you now have it working. Congratulations!
So you are getting different on/off times at diferent distances. I got the same thing. But if you add the on and off times together, do you get the
same totals at a wider range of distances? So for example:
produces this:
44 43 42 44 25 27 27 29 24 --- etc.
If you hold the remote at a different distance, do you get the same result? If you do, then all you have to do is look at the total cycle time, which will be around 44 for a 1 and around 26 for a zero. Have you tried my latest code with the modified circuit?
I've tried it yes but i've already did a lot in my own code so i will modify it, and yes you might be right about the times, using your code i have this :
The only thing i changed was basically the pulldown resistor, it wasn't working properly yesterday, so i just fixed it today and it got to work, now im fixing my code, still having some problems but your idea really is helping me out.
Yes the fixed place for testing the remote is a good idea, but still there is more to it, the TSMP is coming next week too so i will try out managing 2 signals at the same time, but here it is the test with your new code :
That's great! So you may find that the TSMP will work at a much greater range of distances. But at least you know you can finish this successfully even if the TSMP doesn't work for some reason, or never arrives.
Earlier @kmin was looking for a full listing of the six possible codes from the three remotes you have, two buttons each. Me too. I think we have five of the six, but we're missing the second button from #24869. Could you post that?
Damn, you are moving way too fast, my estimation was 600.
So the check code shall be cracked. Assuming that it is check code and not the remote battery voltage...
It is working fine :)) I mean the distance is limited, maybe with the TSMP I can make it with far greater distances, anyways thanks a lot, everyone, I am thinking of posting an resolution post with every info to close the topic