Das leere Gehäuse ging bereits durch mehrere Sammlerhände. Es war von sämtlichem Innenleben befreit und war zuerst nicht zu identifizieren. Es diente unserem Andreas als Opfer zum Demonstrieren einer Schellackpolitur bei dem Treffen im Siegerland. Im Anschluß hat es es mir dann zu Bastelzwecken überlassen. Später stellte sich heraus daß es zu einem Siemens Type 22 gehörte. Ein seltenes Modell, zu dem nicht mal Fotomaterial zu finden war. Für mich ist es ideal um eine Retroversion eines Riesenskala-Radios zu bauen.
Die Konstruktion der Elektronik wiederholt sich eigentlich und ist vergleichbar mit anderen meiner Projekte. Der Arduino-Tuner hat sich in Verbindung mit einem LED-Stripe nun mal bewährt. Die Art der Sendereinstellung ist elegant. Mit einem Impuls des Drehencoders läuft ein Suchlauf richtungsabhängig auf den nächsten empfangbaren Sender.
Die Konstruktion der beiden gespiegelten Frontplattenteile und der Lautsprechergitter:
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:
der Arduinosketch:
/// 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);
}
Moin, Moin :-)
AntwortenLöschenIch 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