IR med Arduino

Berätta om dina pågående projekt.
persika
EF Sponsor
Inlägg: 1357
Blev medlem: 31 juli 2006, 22:14:37
Ort: Österlen, Skåne

Re: IR med Arduino

Inlägg av persika »

Här är en bild till från oscilloskopet. Har "klippt ut" (i Paint) en remsa från vardera mätning med att skicka "on" och "off" från fjärren.
Har lagt remsorna sida vid sida, så man kan se skillnader, på "on" är det två bitar som skiljer, markerat med pilar.
Har läst på internetsidan AnalysIR, för Panasonic ska första delpaketet vara 0x4004072000000060. Det har jag lyckats tyda, långt mellanrum = 1, kort = 0.
Se bifogad bild.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
pi314
Inlägg: 6083
Blev medlem: 23 oktober 2021, 19:22:37
Ort: Stockholm

Re: IR med Arduino

Inlägg av pi314 »

Här är ett projekt som jag råkade se som kanske kan vara användbart?
Universal IR Remote Control
https://github.com/aman-adhav/Universal ... te-Control

/Pi
toolbox
Inlägg: 14
Blev medlem: 20 november 2021, 20:56:32

Re: IR med Arduino

Inlägg av toolbox »

Det finns mer eller mindre färdiga projekt även för Panasonic på Github, t.ex denna: https://github.com/r45635/HVAC-IR-Control
Jag har inte koll på hur korrekt det är, men data som skickas ska vara:

Kod: Markera allt

void sendHvacPanasonic(
 HvacMode                  HVAC_Mode,           // Example HVAC_HOT  HvacPanasonicMode
 int                       HVAC_Temp,           // Example 21  (°c)
 HvacFanMode               HVAC_FanMode,        // Example FAN_SPEED_AUTO  HvacPanasonicFanMode
 HvacVanneMode             HVAC_VanneMode,      // Example VANNE_AUTO_MOVE  HvacPanasonicVanneMode
 HvacProfileMode           HVAC_ProfileMode,    // Example QUIET HvacProfileMode
 int                       HVAC_SWITCH          // Example false
);
Hur det sedan "förpackas" och blir ett färdigt kommando ser man om man tittar vidare i koden, men här visas parametrarna som skickas. Om det fungerar som min Misubishi-pump så skickas alla parametrar i varje kommando, alltså inte bara temperatur eller fläkthastighet eller vilken knapp man nu trycker på. Detta är nödvändigt om man vill att displayen på fjärren ska vara synkroniserad med pumpen. Det kan ju vara så att man trycker på knappar men att signalen inte alltid går fram, då vore det dumt om det står en sak i fjärren och pumpen gör något annat.

Här har du ett annat projekt på Github som är mer komplett och där mängder med värmepumpar finns med. Bl.a. skiljer man mellan Toshiba och Toshiba Daisekai så det verkar finnas mer än ett protokoll från Toshiba: https://github.com/ToniA/arduino-heatpumpir

Koden är okomplicerad och du kan lätt jämföra detta med vad du får ut. Så här ser en del av koden ut för Toshiba-pumpen men återigen så måste du titta i dom andra filerna för att se hur det sedan förpackas i ett Toshiba-formaterat paket. Det är nog enkelt att ta den här koden och helt enkelt testa och se om det fungerar. Och om det inte riktigt blir rätt finns ju IR-Dump som jag tipsade om tidigare som visar dig alla data i paketet i klartext liksom hur det är kodat.

Kod: Markera allt

/*
    Toshiba RAS-10PKVP-ND heatpump control (remote control P/N WH-H07JE)
*/
#ifndef ToshibaHeatpumpIR_h
#define ToshibaHeatpumpIR_h

#include <HeatpumpIR.h>


//Toshiba timing constants
#define TOSHIBA_AIRCON1_HDR_MARK   4400
#define TOSHIBA_AIRCON1_HDR_SPACE  4400
#define TOSHIBA_AIRCON1_BIT_MARK   550
#define TOSHIBA_AIRCON1_ONE_SPACE  1600
#define TOSHIBA_AIRCON1_ZERO_SPACE 550


// Toshiba codes
#define TOSHIBA_AIRCON1_MODE_AUTO  0x00 // Operating mode
#define TOSHIBA_AIRCON1_MODE_HEAT  0xC0
#define TOSHIBA_AIRCON1_MODE_COOL  0x80
#define TOSHIBA_AIRCON1_MODE_DRY   0x40
#define TOSHIBA_AIRCON1_MODE_OFF   0xE0
#define TOSHIBA_AIRCON1_FAN_AUTO   0x00 // Fan speed
#define TOSHIBA_AIRCON1_FAN1       0x02
#define TOSHIBA_AIRCON1_FAN2       0x06
#define TOSHIBA_AIRCON1_FAN3       0x01
#define TOSHIBA_AIRCON1_FAN4       0x05
#define TOSHIBA_AIRCON1_FAN5       0x03

class ToshibaHeatpumpIR : public HeatpumpIR
{
  public:
    ToshibaHeatpumpIR();
    void send(IRSender& IR, uint8_t powerModeCmd, uint8_t operatingModeCmd, uint8_t fanSpeedCmd, uint8_t temperatureCmd, uint8_t swingVCmd, uint8_t swingHCmd);

  private:
    void sendToshiba(IRSender& IR, uint8_t operatingMode, uint8_t fanSpeed, uint8_t temperature, uint8_t swingVCmd, uint8_t swingHCmd);
};

#endif
persika
EF Sponsor
Inlägg: 1357
Blev medlem: 31 juli 2006, 22:14:37
Ort: Österlen, Skåne

Re: IR med Arduino

Inlägg av persika »

Tack för info!
Det verkar finnas mycket information om att sända ir med Arduino, så de känns som att min idé är inom räckhåll.
Antingen kan man ladda ner nåt färdigt library till Arduino, eller så verkar det inte så svårt att programmera något eget (gillar att pilla med sånt).

Jag ska experimentera lite till, med att läsa av fjärrkontrollen, med olika inställningar, temperatur, fläkt, m.m. och se hur ir-koden påverkas och se hur det stämmer med det man hittar på AnalysIR.

Jag mätte upp frekvensen till 36,6 kHz, undrar hur noga det är, ofta ser man i dessa sammanhang 38 kHz ?
persika
EF Sponsor
Inlägg: 1357
Blev medlem: 31 juli 2006, 22:14:37
Ort: Österlen, Skåne

Re: IR med Arduino

Inlägg av persika »

Som jag skrev tidigare mätte jag upp frekvensen till 36,7kHz.

Jag har beställt hem en TSOP38238, ir-mottagare för 38 kHz och en TSOP4836 för 36 kHz.
Båda ger rena och snygga kurvformer, så nu kan jag mäta upp olika kommandon och olika fjärrkontroller.

36 eller 38 kHz verkar inte göra nån skillnad ?
persika
EF Sponsor
Inlägg: 1357
Blev medlem: 31 juli 2006, 22:14:37
Ort: Österlen, Skåne

Re: IR med Arduino

Inlägg av persika »

Nu kan jag läsa av fjärrkontrollen. Skrivit ett program för Arduino Nano med en IR-mottagare TSOP4836.
Får ut data på serieporten radnummer, hexadecimalt, och binärt.
Ett krux var att LSB sänds först i IR-sändningen.

Programmet:

Kod: Markera allt

// Påbörjad 20230909, senast ändrad 20230919
// Program för att läsa av IR från Panasonic LLVP-fjärrkontroll.
// OBS, LSB-bit IR-sänds först i en byte.
// Utskrift på serieport med LSB sist.
//
// För Arduino Nano, ATmega328 16MHz.
// Arduino IDE 1.8.16

#include <datatyper.h>

#define IR_MOTT_PIN 2  // ir mottagare TSOP4836 anslutan till denna pinne
#define UT_PIN 3       // används för felsökning av program, med oscilloskop

#define MdataStorl 27
uInt8 IrMottData[MdataStorl];  // array som mottagna data lagras i 
uInt8 *pIrMData;        // pekar i IrMottData
uInt8 AktNrIrMData;     // aktuell byte i array IrMottData
uInt8 AktBitNrIrMData;  // aktuell bit i aktuell byte i IrMottData

sInt16 AntIimpuls;  // antal 40us perioder i impuls

typedef enum
  {
  tsTom,  // inget mottaget  
  ts1,    // hög 9,9ms impuls mottagen
  ts2,    // låg 3,6ms impuls mottagen 
  tsMott  // hög 1,6ms impuls mottagen och därefter pågår mottagning av databitar
  } 
TillstaandTyp;

TillstaandTyp Tillstaand;


//------------------IrMdataNollstaell------------------
void IrMdataNollstaell()
{
uInt8 a;
a = MdataStorl;
while (a)
  {
  --a;
  IrMottData[a] = 0;
  }
pIrMData = &IrMottData[0];
AktNrIrMData = 0;
AktBitNrIrMData = 0;
}
//------------------IrMdataNollstaell------------------


//------------------IrMdataSkriv-----------------------
void IrMdataSkriv()  // vertikal utskrift
{
uInt8 a;
uInt8 b;
uInt8 n;
uInt8 r;
uInt8 *p;
p = &IrMottData[0];

Serial.println();
n = 0;
r = 0;
a = MdataStorl;
while (a)
  {
  --a;
  ++n;
  ++r;

  // skriv radnummer i avsnitt
  Serial.print(r);
  Serial.print("\t");

  // skriv hex-värde
  Serial.print("'");
  if (*p < 16)
    Serial.print("0");
  Serial.print(*p, HEX);
  Serial.print("\t");

  // skriv bitar
  Serial.print("'");
  b = 8;
  while (b)
    {  
    if (*p & 0x80)
      Serial.print("1");
    else  
      Serial.print("0");
    *p <<= 1;  
    --b;
    }

  // tomrad mellan avsnitt
  if (n == 8)
    {
    Serial.println();
    r = 0;
    }

  // nyrad  
  Serial.println();
  ++p;
  }
Serial.println();
}
//------------------IrMdataSkriv-----------------------



//------------------LaesImpuls--------------------
sInt16 LaesImpuls( sInt16 MaxAntIimpuls )
{  
// Returnerar impuls längd i antal 40us delar, minus om impuls var låg, plus om hög
// Om MaxAntIimpuls ej är noll, då avbryts funktionen vid det antalet och returnerar då noll.
boolean IRpinData;
boolean fgIRpinData; // föregående IRpinData
sInt16 AntIimpuls;   // antal 40us perioder i impuls

AntIimpuls = 0;
IRpinData = digitalRead(IR_MOTT_PIN);  
do
  {
  if (MaxAntIimpuls)  
    {
    if (AntIimpuls < MaxAntIimpuls)
      ++AntIimpuls;
    else
      return 0;  
    }
  else
    {  
    if (AntIimpuls < sInt16Max)
      ++AntIimpuls;
    }
  delayMicroseconds(40);
  fgIRpinData = IRpinData;  
  IRpinData = digitalRead(IR_MOTT_PIN);
  }
while (fgIRpinData == IRpinData);

if (IRpinData)
  return -AntIimpuls;
else  
  return AntIimpuls;
}
//------------------LaesImpuls--------------------


//------------------setup----------------------------
void setup() 
{
pinMode(IR_MOTT_PIN, INPUT);   
//digitalWrite(pin, HIGH);       // turn on pullup resistors

pinMode(UT_PIN, OUTPUT);    // sets the digital pin as output
digitalWrite(UT_PIN, 1);

// Initialise Serial communication, set baud rate = 9600
Serial.begin(9600);
Serial.println("Start");

IrMdataNollstaell();

AntIimpuls = 0;
Tillstaand = tsTom;
}
//------------------setup----------------------------


//------------------loop----------------------------
void loop() 
{

switch(Tillstaand)
  {
  case tsTom:
    if (LaesImpuls(0) > 220)
      Tillstaand = ts1;  
    break;
  case ts1:
    if (LaesImpuls(0) < -74)
      Tillstaand = ts2;  
    else  
      Tillstaand = tsTom;
    break;
  case ts2:
    if (LaesImpuls(0) > 30)
      Tillstaand = tsMott;  
    else  
      Tillstaand = tsTom;
    break;
  case tsMott:
    AntIimpuls = LaesImpuls(0);
    if (!((AntIimpuls < -8) && (AntIimpuls > -15)))
      Tillstaand = tsTom;
    else  
      {
      AntIimpuls = LaesImpuls(250); 
      if ( AntIimpuls == 0 )
        {
        IrMdataSkriv();
        IrMdataNollstaell();
        Tillstaand = tsTom;
        break;  
        }
      if (AntIimpuls < 20)  
        { // Nollbit avläst
          ;
        *pIrMData >>= 1;
        ++AktBitNrIrMData;
        if (AktBitNrIrMData == 8)
          {
          ++pIrMData;  
          AktBitNrIrMData = 0;  
          ++AktNrIrMData;
          if (AktNrIrMData > MdataStorl)
            {
            IrMdataNollstaell();
            Tillstaand = tsTom;
            break;
            }
          }
        }
      else  
      if (AntIimpuls < 35)  
        { // Ettbit avläst
          ;
        *pIrMData = ((*pIrMData >> 1) | 0x80);
        ++AktBitNrIrMData;
        if (AktBitNrIrMData == 8)
          {
          ++pIrMData;  
          AktBitNrIrMData = 0;  
          ++AktNrIrMData;
          if (AktNrIrMData > MdataStorl)
            {
            IrMdataNollstaell();
            Tillstaand = tsTom;
            break;
            }
          }
        }
      else
        Tillstaand = ts1;  
      }
    break;
  }

}
//------------------loop----------------------------

//  digitalWrite(UT_PIN, !digitalRead(UT_PIN));  // test

persika
EF Sponsor
Inlägg: 1357
Blev medlem: 31 juli 2006, 22:14:37
Ort: Österlen, Skåne

Re: IR med Arduino

Inlägg av persika »

Data från programmet, med olika knapptryckningar, kan man jämför data i ett kalkylprogram.
Har gjort lite test med oilka temperaturinställningar på fjärren.
Kommit fram till att det kodas med formel ((önskad temp)-16)x2 + 32 = (databyte för temperatur i IR)
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Skriv svar