Samstag, 9. September 2017

Arduino-Radio mit Leuchtbandanzeige


















//bis jetzt fehlerfreie Funktion!
//Hertel-Library si4703.h
//learning about NeoPixel:
//https://learn.adafruit.com/adafruit-neopixel-uberguide/arduino-library
//
/// 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                |

//http://www.bristolwatch.com/arduino/arduino2.htm

#include <Arduino.h>
#include <Wire.h>
#include <radio.h>
#include <si4703.h>

#include <Adafruit_NeoPixel.h>
#define Din 4
int anz_led = 26; // Anzahl der LED's
Adafruit_NeoPixel strip = Adafruit_NeoPixel(anz_led, Din, NEO_GRB + NEO_KHZ800);
int wc = 0;
int led = 0;

// Input buttons on radio
#define preset 8
#define volDown 9            
#define volUp 10

//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

// Si4703 radio chip
#define FIX_BAND     RADIO_BAND_FM   ///< The band that will be tuned by this sketch is FM.
SI4703 radio;    // Create an instance of Class for Si4703 Chip

// Variables definition
volatile int channel = 8800; // universal count
volatile byte INTFLAG1 = 0; // interrupt status flag
int volume = 10;

void setup()
{
  // Set internal pull up resistors on inputs
  pinMode(preset, INPUT_PULLUP);
  pinMode(volDown, INPUT_PULLUP);      
  pinMode(volUp, INPUT_PULLUP);

  //Rotary Encoder KY-040 pull up's built in
  pinMode (clk, INPUT);
  pinMode (dt, INPUT);

  // interrupt 1 digital pin 3 positive edge trigger
  attachInterrupt(digitalPinToInterrupt(clk), flag, RISING);

  Serial.begin(9600);
  Serial.println(channel);

  // Set all radio setting to the fixed values.
  radio.init();
  radio.setBandFrequency(FIX_BAND, channel);
  radio.setVolume(volume);
  radio.setMono(false);
  radio.setMute(false);
  Serial.println("fixed values");

  //Initialize LED-Stripes
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  strip.setBrightness(64); //range 0 (off) to 255 (max brightness)
  UpdateLed();
  Serial.println("LED-Stripes");

}

void loop()
{
    
  // Volume down
  if (digitalRead(volDown) == LOW)
   {
     if (volume > 0) volume--;
     radio.setVolume(volume);
     delay(100);
   }

  // Volume up
  if (digitalRead(volUp) == LOW)
   {
     if (volume < 15) volume++;
     radio.setVolume(volume);
     delay(100);
   }

  //Rotary Encoder
  if (INTFLAG1)   {
       INTFLAG1 = 0; // clear flag
       Serial.println(channel);
       Serial.println("ISP ausgelöst");
       radio.setFrequency(channel);
       UpdateLed();
       delay(40);
  } // end if  
    
  // Preset-Stationen http://www.w3ii.com/de/arduino/arduino_switch_case_statement.html
  if (digitalRead(preset) == LOW)
  {
    switch (channel){
    case 8800: channel = 9550; break;
    case 9550: channel = 10090; break;
    case 10090: channel = 10170; break;
    case 10170: channel = 10370; break;
    case 10370: channel = 8800; break;
    default: channel = 8800;
    }
    Serial.print("Preset: ");
    Serial.println(channel);
    radio.setFrequency(channel);
    UpdateLed();
    delay(100);
  }
  delay(50);  
}//end loop

//ISR for Encoder: http://www.bristolwatch.com/arduino/arduino2.htm
void flag() {
  INTFLAG1 = 1;
  // add 1 to count for CW
  if (digitalRead(clk) && digitalRead(dt)) {
    channel+=10 ;
    if (channel > 10800) channel = 8700;
  }
  // subtract 1 from count for CCW
  if (digitalRead(clk) && !digitalRead(dt)) {
    channel-=10 ;
    if (channel < 8700) channel = 10800;
  }
}

void UpdateLed()
{
strip.setPixelColor(led, strip.Color( 0, 0, 0));
led = map(channel, 8700, 10800, 0, (anz_led - 1));
strip.setPixelColor(led, Wheel(wc));
strip.show();
delay(20);
}

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);
  }
}

Die kleine hochkantstehende Platine ist ein NF-Verstärker mir LM386. Der genügt völlig um ein mittelgroßes Radio zu betreiben. Die Anordnung der Bauteile ist von der Platine weitgehend vorgegeben, da es sich um eine Steckbrett-Ersatz-Lochrasterplatine handelt. Das spart sehr viele Lötverbindungen.






Keine Kommentare:

Kommentar veröffentlichen