Sonntag, 5. August 2018

Siemens Type 22 Retro Arduino

Bericht vom












Die LED-Viertelkreise fixierte ich mit Panzertape, danach trug ich eine Lage Resin auf der Vorderseite auf. Dadurch sind die LED praktisch in die Frontplatte eingegossen.

Meine Skizze für die IO's und die Anschlußbelegung für Encoder und Stripe. Später änderte sich sich die Spannungsversorgung. Während die + Versorgung noch für einen 9V-Akku gedacht war und auf den V(in) des Arduino gezeichnet ist geht nun die 5V-Versorgung vom Verstärker auf die 5V Vcc des Arduino. Vertauscht hab ich nachträglich CLK und DT am Encoder, damit die Drehrichtung des Abstimmknopfes zur Anzeige passt.



Das Video zeigt eine Vorversion des Radio, bei der ich noch einen Class-D Verstärker benutzte und eine kleine 2.1 Anlage eingebaut war. Später baute ich um auf eine TDA2822M Endstufe im Stereobetrieb.





Das NF-Teil:




Dann hab ich noch einen Platinenhalter gebaut. Die Platine hing vorher nur an den Pin's des Encoders. Jetzt ist es ein richtiges Einbaumodul.




Ich hatte mehrere verschiedene PowerBank zur Spannungsversorgung getestet. Alle hatten ein Problem mit der niedrigen Stromaufnahme des Radio und schalteten nach mehr oder weniger kurzer Zeit ab. Das ging je nach Modell von einem Rhythmus über eine halbe bis zu einer Minute bis hin zum "Blubbern". Als Lösung erwies sich eine kleine Ladeplatine, die ich an einen 18650-Akku anschloß. Damit läuft das Radio sauber durch. Die Ladeplatine ist zudem noch sehr günstig. 5 Stück kosten ca. 1,60€. Der Witz ist: nun kann ich eine PowerBank per USB dazustecken und damit den 18650-Akku während des Radiobetriebs laden ohne Probleme. Eine LED zeigt mir den Ladevorgang (rot) an, wenn der 18650 Akku fertig geladen ist wird sie grün. Ohne externes Ladegerät bleibt die LED aus.






die Rückansicht:








/// SI4703 Nano Rotary Neostrip sketch mit der SI4703_Breakout library von Simon Monk. Auf die aktuellere Version achten! Diese
/// hat bei der Objektdefinition 4 Parameter, die alte Version nur 3.
/// Jupp Haffner 15.9.2017
/// Jupp Haffner 22.9.2017 Speicherung des Senders per EEPROM
/// Siemens31aW Version 3.8.2018
///
/// Wiring
/// ------
/// The SI4703 board has to be connected by using the following connections:
/// | Arduino UNO pin    | Radio chip signal  |
/// | -------------------| -------------------|
/// | 3.3V (red)         | VCC                |
/// | GND (black)        | GND                |
/// | A5 or SCL (yellow) | SCLK               |
/// | A4 or SDA (blue)   | SDIO               |
/// | D2 (white)         | RST                |

#include <Arduino.h>
#include <Wire.h>
#include <radio.h>
#include <Si4703_Breakout.h>
#include <EEPROM.h>

/*SI4703 - Pins*/
int resetPin = 2;
int SDIO = A4;
int SCLK = A5;
int RDSInterruptPin = 3; // GPIO2 for RDS Interrupt

int StereoLED = 11;
int AF_LED    = 12;

/*EEPROM*/
int ChannelEEP=0x01;
//int VolumeEEP=0x02;

int volume = 30;
int rssi; //signal-level
int tune; //AFC
int stereo;

/*Init SI4703 Driver*/
Si4703_Breakout radio(resetPin, SDIO, SCLK, RDSInterruptPin);

//Rotary Encoder http://henrysbench.capnfatz.com/henrys-bench/arduino-sensors-and-input/keyes-ky-040-arduino-rotary-encoder-user-manual/
int clk = 3;  // Connected to CLK on KY-040
int dt = 7;  // Connected to DT on KY-040
int enc_sw = 5; // Connected to SW on KY-040
volatile int channel = 1017;
volatile byte INTFLAG1 = 0; // interrupt status flag
volatile byte UP_FLAG = 0; //seekUp
volatile byte DOWN_FLAG = 0; //seekDn

#include <Adafruit_NeoPixel.h>
#define Din 4 //Ausgabe der LED's über D4
int anz_led = 30; // Anzahl der LED's
Adafruit_NeoPixel strip = Adafruit_NeoPixel(anz_led, Din, NEO_GRB + NEO_KHZ800);
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
int wc = 0; //wheel-color 0 = grün, 80 = rot, 160 = blau
int led = 0;
int led_pos = channel;
int relais = 8; //Relais wird über D8 geschaltet
int ukw = 1;

unsigned long previousMillis = 0;
unsigned long interval = 1000;


void setup()
{

  //Relais
  pinMode(relais, OUTPUT);
   
  //Rotary Encoder KY-040 pull up's built in
  pinMode (clk, INPUT);
  pinMode (dt, INPUT);
  pinMode (enc_sw, INPUT);
  // interrupt 1 digital pin 3 positive edge trigger
  attachInterrupt(digitalPinToInterrupt(clk), flag, RISING); 
       
  //Read last channel and volume
  GetDataFromEEP();
 
  //Initialize and Power up the SI4703
  radio.powerOn();
  radio.powerOn();
  radio.setVolume(volume);
  radio.setChannel(channel);

  //Print Informations to Serial Monitor
  Serial.begin(9600);
  displayInfo();

  //Initialize LED-stripe
  strip.begin();
  strip.setBrightness(64); //range 0 (off) to 255 (max brightness)
  strip.show(); // Initialize all pixels to 'off'
  led_pos = channel;
  UpdateLed();
 
}

void loop()
{

//Abfrage enc_sw
 
     if (!digitalRead(enc_sw) && ukw && (millis() - previousMillis > interval)) {
        //Umschaltung auf AM
        previousMillis = millis();
        ukw = 0;
        Serial.println("UKW 0");
        radio.setVolume(0);
        strip.setBrightness(0);
        UpdateLed();
        digitalWrite(relais, HIGH);
        }
      else if (!digitalRead(enc_sw) && !ukw && (millis() - previousMillis > interval)) {
        //Umschaltung auf FM
        previousMillis = millis();
        ukw = 1;
        Serial.println("UKW 1");
        radio.setVolume(30);
        strip.setBrightness(64);
        UpdateLed();
        digitalWrite(relais, LOW);
      } 
     
    

//Rotary Encoder
  if (INTFLAG1 && ukw)  {
       Serial.println("ISP ausgelöst");
       if (UP_FLAG) SI4703_seekUpAuto(); //Drehrichtung angepasst
       if (DOWN_FLAG) SI4703_seekDnAuto(); //Drehrichtung angepasst
       // clear flags
       INTFLAG1 = 0;
       UP_FLAG = 0;
       DOWN_FLAG = 0;
       }
delay(100);      
} //end loop

//ISR for Encoder: http://www.bristolwatch.com/arduino/arduino2.htm
void flag() {
  if (ukw) INTFLAG1 = 1;
  // CW
  if (digitalRead(clk) && digitalRead(dt)) {
    UP_FLAG = 1;
  }
  // CCW
  if (digitalRead(clk) && !digitalRead(dt)) {
    DOWN_FLAG = 1;
  }
}

void GetDataFromEEP (void)
{
  channel=EEPROM.read(ChannelEEP)+875;
  //volume=EEPROM.read(VolumeEEP);
}

void SetDataToEEP (void)
{  EEPROM.write(ChannelEEP,channel-875);
  //EEPROM.write(VolumeEEP,volume);

}

uint32_t Wheel(byte WheelPos) {
  if (WheelPos < 85) {
    return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if (WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
    WheelPos -= 170;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}

void displayInfo (void)
   {
   rssi=radio.getRSSI();
   tune=radio.getTune();
   stereo=radio.getStereo();
   Serial.print("\n\nChannel: "); Serial.print(channel/10.);Serial.println(" MHz");
   Serial.print("Volume: "); Serial.println(volume);
   Serial.print("RSSI: ");Serial.print(rssi);Serial.println("dB");
   Serial.print("Tune: ");
   if(!tune)Serial.println("AFC Tuned!!");
   if(tune)Serial.println("AFC Tuning...");
   Serial.print("Stereo: ");
   if(stereo){Serial.println("true");digitalWrite(StereoLED, HIGH);}
   if(!stereo){Serial.println("false");digitalWrite(StereoLED, LOW);}
   }

void SI4703_seekUpAuto (void)
{
      channel+=1;
      radio.setVolume(0);
      radio.setChannel(channel);
      delay(20);
      for(int seekup=channel;; seekup++)
      {
         if(seekup>1080)seekup=875;
         Serial.print(seekup/10.);Serial.println(" MHz");
         radio.setChannel(seekup);
         led_pos = seekup;
         UpdateLed();
         delay(10);
         int SI4703AFC_Tune=radio.getTune();
         int SI4703RSSI_Tune=radio.getRSSI();
         delay((SI4703RSSI_Tune*4));
         if(((SI4703AFC_Tune==false)&&(SI4703RSSI_Tune>18)))
         {
            radio.setVolume(volume);
            channel=seekup;
            SetDataToEEP();
            displayInfo();
            break;
         }
      }     
}

void SI4703_seekDnAuto (void)
{
      channel-=1;
      radio.setVolume(0);
      radio.setChannel(channel);
      delay(20);
      for(int seekdown=channel;; seekdown--)
      {        
         if(seekdown<=875)seekdown=1080;
         Serial.print(seekdown/10.);Serial.println(" MHz");
         radio.setChannel(seekdown);
         led_pos = seekdown;
         UpdateLed();
         delay(10);
         int SI4703AFC_Tune=radio.getTune();
         int SI4703RSSI_Tune=radio.getRSSI();
         delay((SI4703RSSI_Tune*4));
         if(((SI4703AFC_Tune==false)&&(SI4703RSSI_Tune>18)))
         {
            radio.setVolume(volume);
            channel=seekdown;
            SetDataToEEP();
            displayInfo();
            break;
         }
      }
}

void UpdateLed()
{
 rssi=radio.getRSSI();
 tune=radio.getTune();
 stereo=radio.getStereo();
 strip.setPixelColor(led, strip.Color( 0, 0, 0));
 led = map(led_pos, 875, 1080, 0, (anz_led - 1));
 wc = 0; //grün
 if (rssi >= 25) wc = 80; //rot
 if (tune) wc = 160; //blau
 strip.setPixelColor(led, Wheel(wc));
 strip.show();
 delay(20);
}
 

1 Kommentar:

  1. Moin, Moin :-)
    Ich finde das Radio echt cool. Habs schon mal nachgebaut und funzt, ich habe noch ein kleines OLED 128x32, das würde ich gerne noch mit einbringen, entweder für die Frequenz oder später viell. RDS daten. Das Problem ist, ich stecke beim Aduino noch in der Krabbelstzube und bekomme die Programmierung nicht hin. Würde da gerne Hilfe vom Profi annehemen. Ein PCB für die Schaltung habe ich breits fast fertig. Ich würde davon auch gern ein paar Platten dafür abgeben.

    MFG Marco

    AntwortenLöschen