Pico infrared not transmitting correctly

Posted on
  • Hello,

    I'm having some trouble getting infrared to correctly transmit from the Pico. Using the same PWM data (microseconds) and components I'm able to see it working using an arduino.

    The Pico is running 1v87 and I was unable to get the Pico infrared example transmitting (receiving is working and also reads the same values as the arudino).

    Minimal arduino sketch based on Arduino-IRremote

    [#include](https://forum.espruino.com/se­arch/?q=%23include) <Arduino.h>
    
    [#define](https://forum.espruino.com/sea­rch/?q=%23define) SYSCLOCK  16000000
    [#define](https://forum.espruino.com/sea­rch/?q=%23define) IR_USE_TIMER2 
    
    unsigned int powerOn[] = { 
      3502,
      1750,
      etc...
      0
    };
    
    void setPwmFrequency(int khz) {
      const uint8_t pwmval = SYSCLOCK / 2000 / (khz); 
      TCCR2A = _BV(WGM20); 
      TCCR2B = _BV(WGM22) | _BV(CS20); 
      OCR2A = pwmval; 
      OCR2B = pwmval / 3;
    }
    
    void enablePwm() {
      (TCCR2A |= _BV(COM2B1));
    }
    
    void disablePwm() {
      (TCCR2A &= ~(_BV(COM2B1)));
    }
    
    void sendCommand(unsigned int command[], unsigned int size) {
      for (signed int i = 0; i < size - 1; i = i + 2) {
        enablePwm();
        delayMicroseconds(command[i]);
        disablePwm();
        delayMicroseconds(command[i + 1]);
      }
      disablePwm();
    }
    
    void setup() {
      pinMode(9, OUTPUT);
      digitalWrite(9, LOW); 
      setPwmFrequency(35);
    }
    
    void loop() {
      signed int size = sizeof(powerOn)/sizeof(int);
      sendCommand(powerOn, size);
      delay(5000);
    }
    

    Pico code

    function toMillis(i) {
       return i / 1000;
    }
    
    var powerOn = [
      3502,
      1750,
      etc...
      0
    ].map(toMillis);
    
    analogWrite(A5, 1, {freq:35000});
    digitalPulse(A6, 1, powerOn);
    digitalPulse(A6, 1, 0);
    analogWrite(A5, 0, {freq:35000}); // without this the IR LED never turns off
    

    Unfortunately I don't have an oscilloscope at hand to see what A5/A6 are actually outputting :(
    Am I missing something obvious?

    Thanks!

  • Try analogWrite(A5,0.5,{freq:35000});
    This should give you a 50% duty cycle.

  • This link might help. Note it uses a 0.9 duty cycle.

    http://www.espruino.com/Pico+Infrared

    Since you don't have a scope you might try this one liner to see the LED flashing.
    analogWrite(A5,0.5,{freq:0.5});
    It uses a lower frequency so you can see the flashes.

    I did this one liner to flash the Green LED on a Pico. This is not PWM pin so you have to use the software PWM. PWM pins use the Timer peripherals built into the ARM chip.
    analogWrite(B12,0.5,{freq:0.5,soft:true}­);

  • ahhh the duty cycle, that was my problem, thank you!

    I also had to replace the initial start value with 0.

    analogWrite(A5, 0.5,{freq: 35000});
    digitalPulse(A6, 0, command);
    digitalPulse(A6, 1, 0);
    
  • Isn't the right frequency 38000 Hz?

    As @ClearMemory041063 said there's some example code at http://www.espruino.com/Pico+Infrared

    The start value will depend on which way you put the IR transmitter between the 2 pins :)

    It might also be handy to make the duty cycle 0.9 as in the example now you're pulling down to turn on. It means the LED is then only on for 10% of the time - which means you can use lower resistor values to drive it with more power without risking breaking it. Also I think it's closer to what the IR receivers expect.

    But hey, if it's working :) Also, for turning off, just try digitalRead(A5) - it'll put the pin into an input state

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Pico infrared not transmitting correctly

Posted by Avatar for Adam @Adam

Actions