Privates Braun-Forum

Für Liebhaber und Sammler der Braun-Unterhaltungselektronik
Aktuelle Zeit: 16.12.2018, 16:41

Alle Zeiten sind UTC + 1 Stunde




Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: senden der RC1 codes mit Arduino
BeitragVerfasst: 13.09.2017, 07:56 
Offline
Eroberer
Eroberer

Registriert: 13.09.2017, 07:18
Beiträge: 89
Hallo,

da ich meine Braun Anlage mit einer Universalfernbedienung bedienen will, und keine RC1 habe (hat mir optisch nie gefallen, und ich möchte nur zum Tasten kopieren keine kaufen), habe ich mir schnell mit einem Arduino MEGA2560 Board eine Software geschrieben mit dem man die Codes senden kann. An Hardware ist nur eine Infrarot LED gegen 5V an Pin 9 notwendig. Man kann ueber serielle Schnittstelle einen Tastencode eingeben, der dann gesendet wird. Die Codes sind gleich mit den Codes fuer die serielle Schnittstelle am R4/CC4:

Code:
01 - 5
02 - 4
03 - 3
04 - 2
05 - 1
06 - Prog +
07 - Prog -
08 - Memo
09 - P10
0a - 9
0b - 8
0c - 7
0d - 6
0e - TAPE1
0f - TAPE2
10 - TREB OFF
11 - FORWARD
12 - REWIND
13 - STOP
14 - PAUSE
15 - START
16 - ?
17 - LBASS
18 - H BLEND
19 - RESET
1a - SET
1b - MEMO
1c - SPACE
1d - REC
1e - MAN TUNE +
1f - MAN TUNE -
20 - BASS OFF
21 - SP1/2 3/4
22 - CLOCK
23 - MONO
24 -
25 - MONITOR
26 - BASS+
27 - BASS-
28 - BAL RESET
29 - BAL R
2a - BAL L
2b - TREB OFF
2c - BASS OFF
2d - LOUDN
2e - TREB +
2f - TREB -
30 - 20 HZ
31 - STBY
32 - VOL+
33 - VOL-
34 - MUTE
35 - EQ OFF
36 - VOL2+
37 - VOL2-
38 - AM
39 - T-
3a - TV
3b - AM/FM
3c - PHONO
3d - CD
3e - SPEAKER 1
3f - SPEAKER 2


Die Software:

Code:
void setup()
{
  Serial.begin(115200);
  pinMode(3, OUTPUT);
  pinMode(9, OUTPUT);
  TCCR2A = _BV(COM2A0) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
  TCCR2B = _BV(WGM22) | _BV(CS21);
  OCR2A = 0;
  OCR2B = 39;
}

void send_bit(uint16_t state)
{
  OCR2A=59;
  delayMicroseconds(160);
  OCR2A=0;
  // H: 8.64ms, L=5.76ms
  delayMicroseconds(state ? 8340: 5500);
}

volatile uint8_t gtoggle = 0;

void transmit_recs80(uint8_t dev, uint8_t toggle, uint8_t command)
{
  uint8_t i;
  uint16_t val = (1 << 11) | (toggle << 10) | ((dev & 7) << 7) | ((command & 0x3f) << 1);
  for(i = 0; i < 12; i++) {
      send_bit(val & (1 << (11 - i)));
  }
}

void loop()
{
  int i;
  String s;
  uint8_t val;
  for(;;) {
    s = Serial.readStringUntil('\n');
    if (s.length() > 0) {
      val = strtoul(s.c_str(), NULL, 16);
      Serial.println(val, 16);
      for(i = 0; i < 16; i++) {
        transmit_recs80(2, gtoggle, val);
        delay(52);
      }
    gtoggle ^= 1;
  }
   
  }
}


Vielleicht ist das ja fuer den einen oder anderen nuetzlich.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: senden der RC1 codes mit Arduino
BeitragVerfasst: 13.09.2017, 08:22 
Offline
Moderator
Moderator
Benutzeravatar

Registriert: 28.12.2010, 15:36
Beiträge: 1738
Wohnort: 85077 Manching
Moin.
Bedeutet das, Du sagst mit den Nummerntasten Deiner Universalfernbedienung dem Arduino, er soll das entsprechende Signal senden?
Oder bedienst Du den Arduino über Tastatur und gibst im Zehnerblock den Code ein?
Gruß, Gereon

_________________
...meistens ist es was Mechanisches...
- wenn es nicht will, wende Gewalt an;
geht es kaputt, hätte es eh gewechselt werden müssen... :wink:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: senden der RC1 codes mit Arduino
BeitragVerfasst: 13.09.2017, 08:31 
Offline
Eroberer
Eroberer

Registriert: 13.09.2017, 07:18
Beiträge: 89
Hallo,

ich gebe mit dem Computer den Code in den Arduino ein, und der Arduino sendet dann den entsprechenden Code.

Viele Grüße
Sven


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: senden der RC1 codes mit Arduino
BeitragVerfasst: 27.10.2017, 23:27 
Offline
Eroberer
Eroberer
Benutzeravatar

Registriert: 17.11.2011, 23:50
Beiträge: 85
Wohnort: 70191 Stuttgart
Hallo Sven,

hast du dich zufällig auch mal mit dem Empfang der RC1 Codes über einen Arduino beschäftigt?

Gruß Flo

_________________
Gruß Flo


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: senden der RC1 codes mit Arduino
BeitragVerfasst: 28.10.2017, 21:17 
Offline
Eroberer
Eroberer

Registriert: 13.09.2017, 07:18
Beiträge: 89
Hallo eleflo,

eleflo hat geschrieben:
hast du dich zufällig auch mal mit dem Empfang der RC1 Codes über einen Arduino beschäftigt?


Ja, habe ich - wobei ich nicht sagen wie stabil das ganze funktioniert, aber bevor ich mit dem senden der Codes angefangen habe, hatte ich ein kleines Testprogramm zum empfangen geschrieben. Da ist allerdings schon etwas code mit drin um die Audioprozessoren zu programmieren, aber vielleicht hilft dir das ja als Grundlage:

Code:
static volatile uint8_t ir_bitcnt = 0;
static volatile uint16_t ir_cmd;
static volatile uint16_t times[32];
static volatile uint8_t tmp_bitcnt;
static volatile uint8_t tmo = 0;

#define STR7976 40
#define STR789 43
#define CLOCK 45
#define DATA 47

static void icp_setup(void)

{
  TCCR4A = 0;
  TCCR4B = _BV(CS41);
  TIMSK4 = _BV(ICIE4) | _BV(TOIE4);
 
  TCCR1A = 0;
  TCCR1B = _BV(CS10) | _BV(CS11);
  TIMSK1 = _BV(TOIE1);
}

void setup()
{
  Serial.begin(115200);
  pinMode(30, INPUT);
  digitalWrite(STR7976, 0);
  digitalWrite(STR789, 0);
  digitalWrite(CLOCK, 0);
  digitalWrite(DATA, 0);
 
  pinMode(STR7976, OUTPUT);
  pinMode(STR789, OUTPUT);
  pinMode(CLOCK, OUTPUT);
  pinMode(DATA, OUTPUT);
  pinMode(7, OUTPUT);
  icp_setup();
}
#define DELAY 300

void send_789(uint16_t value)
{
  int i;
  for(i = 0; i < 16; i++) {
    digitalWrite(DATA, !(value & (0x8000 >> i)));
    delayMicroseconds(DELAY);
    digitalWrite(CLOCK, 1);
    delayMicroseconds(DELAY);
    digitalWrite(CLOCK, 0);
    delayMicroseconds(DELAY);
  }
  digitalWrite(DATA, 0);
  delayMicroseconds(DELAY);
  digitalWrite(STR789, 1);
  delayMicroseconds(DELAY*2);
  digitalWrite(STR789, 0);
}


void send_7976(uint16_t value)
{
  int i;
  for(i = 0; i < 11; i++) {
    digitalWrite(DATA, !(value & (0x400 >> i)));
    delayMicroseconds(DELAY);
    digitalWrite(CLOCK, 1);
    delayMicroseconds(DELAY);
    digitalWrite(CLOCK, 0);
    delayMicroseconds(DELAY);
  }
  digitalWrite(DATA, 0);
  delayMicroseconds(DELAY);
  digitalWrite(STR7976, 1);
  delayMicroseconds(DELAY*2);
  digitalWrite(STR7976, 0);
}

uint16_t encode789_volume(int left, int right)
{
  uint16_t ret = 0x8080;
 
  ret |= (left % 10) + 6;
  ret |= ((right % 10) + 6) << 8;
  ret |= (left / 10) << 4;
  ret |= (right / 10) << 12;
  return ret;
}

uint16_t encode789_contro(int input, int monitor, int mute, int treble, int bass)
{
  uint16_t ret = 0x4200;
 
  ret |= ((input & 3) << 14);
  ret |= ((monitor & 3) << 10);
  ret |= ((mute & 1) << 8);
  ret |= ((treble & 15) << 4);
  ret |= (bass & 15);
  return ret;
}

void loop()
{
  uint16_t tmp;
  static uint8_t vol = 20;

  if (ir_cmd & 0x8000) {
    Serial.println(ir_cmd & 0x3f, HEX);
    //tmp = encode789(0, 1, 1, 0x9, 0xa);
    //Serial.println(tmp, HEX);
    //send_789(0xa7a7);
    switch(ir_cmd & 0x3f) {
      case 0x36:
        /* Volume up */
        vol++;
        if (vol > 80)
          vol = 80;
        break;
      case 0x37:
        /* volume down */
        if (vol > 0)
          vol--;
      case 0x34:
        send_7976(0x0091);
        send_7976(0x0051);
        break;
      default:
         break;     
    }
    //send_789(encode789_volume(vol, vol));
    ir_cmd = 0;
  }
}

ISR(TIMER4_CAPT_vect)
{
  uint16_t val = ICR4;
  bool rising_edge = TCCR4B & _BV(ICES4);
 
  TCCR4B ^= _BV(ICES4);
  TCNT4 = 0;
  TIFR4 |= _BV(ICF4);

  if (ir_cmd & 0x8000)
      return;

  if (ir_bitcnt == 0 && !rising_edge) {
    if (val > 20000)
      ir_bitcnt++;
    /* ignore first falling edge */
    return;
  }

  if ((rising_edge && (val < 200 || val > 800)) ||
     ((!rising_edge && (val < 10000 || val > 18000)))) {
       /* invalid bit length */
        ir_bitcnt = 0;
        ir_cmd = 0;
        return;
  }
 
  /* data is only encoded in the low bit length */
  if (rising_edge)
      return;

  ir_cmd |= (((val > 13000) ? 1 : 0) << (11-ir_bitcnt));
  ir_bitcnt++;
 
  if (ir_bitcnt == 12) {
    ir_cmd |= 0x8000;
    ir_bitcnt = 0;
  }
}

ISR(TIMER4_OVF_vect)
{
  int i;
  TCCR4B &= ~_BV(ICES4);
  TIFR4 |= _BV(ICF4);
  TCNT4 = 0x20001;
  ir_bitcnt = 0;
  ir_cmd = 0;
}

ISR(TIMER1_OVF_vect)
{
  static int value;
  TCNT1 = 0xcf20;
  value ^= 1;
  digitalWrite(7, value);
}



Viele Grüße
Sven


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: senden der RC1 codes mit Arduino
BeitragVerfasst: 26.10.2018, 12:57 
Offline
Mitglied
Mitglied

Registriert: 30.09.2016, 21:17
Beiträge: 30
Hallo Sven,

ich habe deine Codes auf einen Arduino Uno umgesetzt, und es läuft.
Ich kann die IR Signale dekodieren und ich kann auch welche senden.

ich habe da noch eine Frage zu deinem Sendecode.
Im Bereich send_bit werden ja die Pulse für die IR-Diode erzeugt. Du hast auch in einer Kommentarzeile die Delayzeiten für ein High und ein Low angegeben.
Wenn ich aber von diesen Zeiten die 160us für den Burst abziehe, kommen etwas höhere Werte raus als du bei delayMicroseconds warten lässt. Hat das einen tieferen Grund?

MfG

Rainer


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 

Alle Zeiten sind UTC + 1 Stunde


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de