0
\$\begingroup\$

So im using ESP32 to output 38khz 40% duty cycle wave to ir led and connecting a vs1838b on the other side. The vs1838b works as it outputs LOW when i send a signal from my remote. Anyways, after the code is uploaded, vs1838b works for less than a second then produces continuous HIGH signal. So what amends do i have to make for my code for break beam to work properly?

const int IrLedPin = 4;  
const int RecLedPin= 13;

const int freq = 38000;
const int ledChannel = 0;
const int resolution = 8;

    void setup(){
      Serial.begin(115200);
      pinMode(RecLedPin,INPUT);
      // configure LED PWM functionalitites
      ledcSetup(ledChannel, freq, resolution);


      // attach the channel to the GPIO to be controlled
      ledcAttachPin(IrLedPin, ledChannel);
      ledcAttachPin(2,ledChannel1);
      ledcWrite(0,102);

    }


    void loop(){
    Serial.println(digitalRead(RecLedPin));
    delay(50);
    }

Edited: The code is now optimized for software modulated pwm.

// the number of the LED pin
const int IrLedPin = 4;  // 16 corresponds to GPIO16
const int RecLedPin= 13;
const int timer=2;
// setting PWM properties
const int freq = 38000;
const int ledChannel = 0;
const int resolution = 8;
unsigned long timer1;
unsigned long timer2=millis();
 const int freq1= 600;
 const int ledChannel1=1;
 const int resolution1=8;
 unsigned long timer3=micros();
 unsigned long timer4;
bool recieve;
void setup(){
  Serial.begin(115200);
  pinMode(RecLedPin,INPUT);
  // configure LED PWM functionalitites
  ledcSetup(ledChannel, freq, resolution);
  ledcAttachPin(IrLedPin, ledChannel);

  pinMode(16,INPUT);
}


void loop(){
  recieve=digitalRead(RecLedPin);
  timer1= timer2-millis();
  timer4=timer3-micros();
  if (timer1>50) {
Serial.println(recieve);
timer2=millis();
  }
 if (timer4<600){
  ledcWrite(0,102);
  } else if (timer4>600 && timer4<900){
    ledcWrite(0,0);
    } else if (timer4>900) {
      timer3=micros();
      }
}
\$\endgroup\$
5
  • \$\begingroup\$ i can do double modulation if it is a requirement, just add a transistor, put the 38KHz signal on collector and the second signal on the transistor base. \$\endgroup\$ – Informal Limits Lad Apr 11 '20 at 15:13
  • \$\begingroup\$ Yes, double modulation. The IR receiver wants a burst of 38 kHz lasting about 600us, followed by a rest-period of 900us - 5000us. \$\endgroup\$ – glen_geek Apr 11 '20 at 15:38
  • \$\begingroup\$ so what frequency and duty cycle should i set it to? \$\endgroup\$ – Informal Limits Lad Apr 11 '20 at 15:41
  • \$\begingroup\$ so i did it with 666 hz, and a duty cycle of 40 percent but it doesnt work. i used the following calculation, total period of pulse 600+900=1500 us. 1/1500x10^-6= 666hz. \$\endgroup\$ – Informal Limits Lad Apr 11 '20 at 16:34
  • \$\begingroup\$ 600/1500 x 100= 40 percent duty cycle. \$\endgroup\$ – Informal Limits Lad Apr 11 '20 at 16:35
0
\$\begingroup\$

IR receiver modules like you have typically reject continous 38kHz signal. You need to send for example a 500 microsecond burst of 38 kHz signal and then pause for some time - optimum value depends on how the AGC is tuned to allow optimum reception of certain kinds of common IR remote protocols. The datasheet of your module says it is tested with a signal of 600 microseconds of 38 kHz burst following a 900 microsecond pause, so it is a reasonable starting point for transmitting your signal.

\$\endgroup\$
4
  • \$\begingroup\$ I just added my current 38khz 40% duty cycle signal to collector of a transistor with the IR led in series. Emitter to ground. Then i added the second signal to base of the transistor to achieve double modulation. The second signal i calculated 1/((600+900)x10^-6) was about 666hz, and duty cycle was 600/(600+1500) = 40%. But it still doesnt work. any reason why? \$\endgroup\$ – Informal Limits Lad Apr 12 '20 at 6:06
  • \$\begingroup\$ Hard to say. Your description is not very detailed. Post the schematics with all component types and values. You don't mention a base resistor though - maybe something is now broken? Is there any reason to mix the signals with external components, while you could toggle the 38 kHz PWM on and off in software? \$\endgroup\$ – Justme Apr 12 '20 at 7:46
  • \$\begingroup\$ didnt add the base resistor. and the reciever still works as i tested it with an ir remote. Ill post the schematic and the new code. \$\endgroup\$ – Informal Limits Lad Apr 12 '20 at 8:26
  • \$\begingroup\$ so i have removed the transistor. And edited the code to produce modulated pwm through software. but it isnt working. The Led doesnt light up. Previously it showed red color. \$\endgroup\$ – Informal Limits Lad Apr 12 '20 at 13:56
0
\$\begingroup\$

I have figured it out. Set up VS1838b as shown in the diagram in this link: https://www.electronicoscaldas.com/datasheet/VS1838B-M-WCON_Manual.pdf

This will help remove any operational instability or false triggering from the receiver. You can ignore it if you want and just connect the output directly.

It is recommended that the emitter/IR LED should be of high quality and 940nm wavelength . As a rule of thumb, avoid emitters that give off visible light.

Notes on the code:

  1. Since these photo-transistors are chinese-made and not of very high quality, so you may have to experiment manually. Instructions are given in the code.
  2. This code is written for ESP32 Devkit-V1 or Wroom.
  3. If you have reached the 1 ms on-time, and believe that fine tuning can be done further then you will have to use micros() for the associated timers.
  4. Whenever adjusting pulses, make sure that the ratio of on time to total pulse time is 0.4 or 40 % duty cycle.
  5. Make sure to read the comments first.
  6. It will not be much sensitive. In other words, the obstacle should break the line of sight for almost 26ms for the receiver to detect something. This also accounts to 26ms lag.

Code:

//Whenever the pulse is broken, the reciever outputs HIGH.
const int IrLedPin = 4;  
const int RecLedPin= 13;

const int freq = 38000; //38Khz Continuous Wave
const int ledChannel = 0;
const int resolution = 8;

unsigned long timer1; //Timers For Modulating The Continuous Wave To Pulses
unsigned long timer2=millis(); // The values of these can be adjusted by viewing the 
unsigned long timer3; // serial plotter output which would be correct
unsigned long timer4; // if we can see a modulated signal there.
unsigned long lastLowMillis;

bool recieve; //boolean value of current signal
unsigned long intervalMillis= 26; //This should be greater then the off time of pulses, in my case 40-16= 24,add a few milliseconds just to be precise. I have added only 2 milliseconds. 24+2 = 26.
//This  would determine the time elapsed by the high signal which should be greater than off time so that the microcontroller realises that its path is being broken by an obstacle.
void setup(){
  Serial.begin(115200);
  pinMode(RecLedPin,INPUT);
  // configure LED PWM functionalitites
  ledcSetup(ledChannel, freq, resolution);

  ledcAttachPin(IrLedPin, ledChannel);

 ledcWrite(0,102);
 timer3=millis();
}


void loop(){
  recieve=digitalRead(RecLedPin);
  timer1= timer2-millis();
  timer4= millis()-timer3;

  if (timer1>50) {
Serial.println(recieve); //Display Values Of Signal. Every 50 Milliseconds.
timer2=millis();
  }
 if (timer4<16){ //Determine On time. In my case 16ms.
  ledcWrite(0,102);
 } else if (timer4>16 && timer4<40) //Deterime Off Time. In my case (40-16= 24ms )
 { // In my case, the total time for the pulse is 16+24= 40ms
   // Making sure duty cycle is 40% or 0.4 hence 16/40 = 0.4 . Formula for calculating duty cycle On-Time/Total-Time.
  ledcWrite(0,0);
  } else if (timer4>40){ // After a pulse has been generated, then reset the timer for another pulse. Think Of it as PWM on PWM (Double PWM).
    timer3=millis();
    }
    //The following code  should be executed after you have done the fine tuning. If you have not, then either remove it or comment it out.
if (recieve == LOW) { //Detecting when the reciever's line of sight has been broken.
   lastLowMillis = millis();
} else if (millis() - lastLowMillis > intervalMillis) { //I have mentioned how to set the interval millis.
   // Serial.println("Step Detected"); // After setting up of interval you can add this line.If not then leave it commented out. Also remove the code of timer1 and printing recieve as it will interfere in serial monitor.
   lastLowMillis=0;
}
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.