Arduino Radio

Nachdem mein erstes “Projekt” nun schon seit einigen Monaten super läuft (https://forum.arduino.cc/index.php?topic=574644.0) habe ich mich an mein 2. Projekt gestürzt. Aber auch da habe ich Probleme.
Ich möchte ein einfaches Radio mit dem Arduino bauen. Und zwar dieses: Arduino Radio with RDS | Hackaday.io

Leider bekomme ich nur Fehlermeldungen und stehe im Moment “auf dem Schauch”

#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <Wire.h>
#include <radio.h>;

#define SHOW_STATION 0
#define SHOW_VOLUME  1
#define SHOW_TUNING  2


byte CHR_ANTENNA[8] = {
 B11111, B10101, B10101, B01110, B00100, B00100, B00100, B00100
};

byte CHR_STRENGTH[8][8] = {{
 B00000, B00000, B00000, B00000, B00000, B00000, B00000, B10000
}, {
 B00000, B00000, B00000, B00000, B00000, B00000, B11000, B10000
}, {
 B00000, B00000, B00000, B00000, B00000, B11000, B11000, B10000
}, {
 B00000, B00000, B00000, B00000, B11100, B11000, B11000, B10000
}, {
 B00000, B00000, B00000, B11100, B11100, B11000, B11000, B10000
}, {
 B00000, B00000, B11110, B11100, B11100, B11000, B11000, B10000
}, {
 B00000, B11110, B11110, B11100, B11100, B11000, B11000, B10000
}, {
 B11111, B11110, B11110, B11100, B11100, B11000, B11000, B10000
}};


byte CHR_BAR[7][8] = {{
 B11111, B00000, B00000, B00000, B00000, B00000, B00000, B11111
}, {
 B11111, B00000, B11000, B11000, B11000, B11000, B00000, B11111
}, {
 B11111, B00000, B11011, B11011, B11011, B11011, B00000, B11111
}, {
 B01111, B11000, B10000, B10000, B10000, B10000, B11000, B01111
}, {
 B11110, B00011, B00001, B00001, B00001, B00001, B00011, B11110
}};



LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
Radio radio;


byte currentDisplay = SHOW_STATION;
long displayTimeout;
long lastKeyPress;


void setup() {
 lcd.begin(16, 2);
 lcd.createChar(0, CHR_ANTENNA);
 lcd.createChar(1, CHR_STRENGTH[7]);
 lcd.createChar(2, CHR_BAR[0]);
 lcd.createChar(3, CHR_BAR[1]);
 lcd.createChar(4, CHR_BAR[2]);
 lcd.createChar(5, CHR_BAR[3]);
 lcd.createChar(6, CHR_BAR[4]);

 lcd.clear();
 lcd.setCursor(0, 0);
 lcd.print("     Radio?     ");

 if (!radio.init()) {
 lcd.setCursor(0, 1);
 lcd.print("Radio error!    ");
 while(true);
 }
 // tuneTo(87.6);

 if (EEPROM.read(0) == 'R' && EEPROM.read(1) == 'A' && EEPROM.read(2) == 'D' && EEPROM.read(3) == 'I' && EEPROM.read(4) == 'O') {
 radio.tuneTo(getEepromFreq());
 radio.setVolume(getEepromVolume());
 } else {
 EEPROM.update(0, 'R');
 EEPROM.update(1, 'A');
 EEPROM.update(2, 'D');
 EEPROM.update(3, 'I');
 EEPROM.update(4, 'O');
 setEepromVolume(4);
 }

 radio.setBassBoost(true);
 radio.setMute(false);

 lastKeyPress = millis();
 displayTimeout = 0;
}


void loop() {
 radio.updateStatus();
 if (!radio.state.isTunedToChannel && currentDisplay == SHOW_STATION) {
 currentDisplay = SHOW_TUNING;
 displayTimeout = 0;
 } else if (currentDisplay == SHOW_TUNING && radio.state.isTunedToChannel) {
 currentDisplay = SHOW_STATION;
 setEepromFreq(radio.state.frequency);
 }

 handleKeys();
 updateDisplay();
 delay(10);
}


void handleKeys() {
 unsigned short keyState = analogRead(0);
 if (keyState == 1023 || millis() - lastKeyPress < 100) return;

 switch (keyState) {
 case 99:
 if (radio.state.volume < 15) {
 radio.setVolume(radio.state.volume + 1);
 displayTimeout = millis() + 5000;
 currentDisplay = SHOW_VOLUME;
 }
 break;

 case 255:
 if (radio.state.volume > 0) {
 radio.setVolume(radio.state.volume - 1);
 displayTimeout = millis() + 5000;
 currentDisplay = SHOW_VOLUME;
 }
 break;

 case 408:
 radio.seekDown();
 break;

 case 0:
 radio.seekUp();
 break;
 }

 lastKeyPress = millis();
}



void updateDisplay() {
 if (currentDisplay != SHOW_STATION && displayTimeout != 0 && millis() > displayTimeout) {
 if (currentDisplay == SHOW_VOLUME) {
 setEepromVolume(radio.state.volume);
 }
 lcd.clear();
 currentDisplay = SHOW_STATION;
 }

 drawStatusLine();

 switch (currentDisplay) {
 case SHOW_STATION:
 lcd.setCursor(0, 1);
 if (radio.state.hasStationName) {
 lcd.print("    ");
 lcd.print(radio.state.stationName);
 lcd.print("    ");
 } else {
 lcd.print("                ");
 }
 break;

 case SHOW_VOLUME:
 lcd.setCursor(0, 1);
 lcd.print("Volume ");
 lcd.write(byte(5));
 for (byte i = 0; i < 7; i ++) {
 if (radio.state.volume > i * 2 + 1) {
 lcd.write(byte(4));
 } else if (radio.state.volume > i * 2) {
 lcd.write(byte(3));
 } else {
 lcd.write(byte(2));
 }
 }
 lcd.write(byte(6));
 break;

 case SHOW_TUNING:
 lcd.setCursor(0, 1);
 lcd.print("  Searching...  ");
 break;
 }
}


void drawStatusLine() {
 lcd.setCursor(0, 0);
 lcd.print(radio.state.frequency);
 lcd.print(" MHz   ");

 switch (radio.state.signalStrength) {
 case 0 ... 1:
 lcd.createChar(1, CHR_STRENGTH[0]);
 break;
 case 2 ... 13:
 lcd.createChar(1, CHR_STRENGTH[1]);
 break;
 case 14 ... 24:
 lcd.createChar(1, CHR_STRENGTH[2]);
 break;
 case 25 ... 34:
 lcd.createChar(1, CHR_STRENGTH[3]);
 break;
 case 35 ... 43:
 lcd.createChar(1, CHR_STRENGTH[4]);
 break;
 case 44 ... 51:
 lcd.createChar(1, CHR_STRENGTH[5]);
 break;
 case 52 ... 57:
 lcd.createChar(1, CHR_STRENGTH[6]);
 break;
 case 58 ... 63:
 lcd.createChar(1, CHR_STRENGTH[7]);
 break;
 }
 lcd.setCursor(14, 0);
 lcd.write(byte(0));
 lcd.write(byte(1));
}


float getEepromFreq() {
 float frequency = 0.0f;
 frequency += EEPROM.read(6)  * 100.0f;
 frequency += EEPROM.read(7)  * 10.0f;
 frequency += EEPROM.read(8);
 frequency += EEPROM.read(9)  / 10.0f;
 frequency += EEPROM.read(10) / 100.0f;
 return frequency;
}


byte getEepromVolume() {
 return EEPROM.read(11);
}


void setEepromFreq(float frequency) {
 unsigned short freq = frequency * 100;
 EEPROM.update(6, (freq / 10000));
 EEPROM.update(7, (freq / 1000) % 10);
 EEPROM.update(8, (freq / 100) % 10);
 EEPROM.update(9, (freq / 10) % 10);
 EEPROM.update(10, freq % 10);
}


void setEepromVolume(byte volume) {
 EEPROM.update(11, volume);
}

Fehlermeldungen:
Arduino: 1.8.7 (Windows 10), Board: “Arduino/Genuino Uno”

C:\Users\Tom\Downloads\ArduinoRadio_v1.1\lcdRadio\lcdRadio.ino:4:19: warning: extra tokens at end of #include directive

#include <radio.h>;

^

In file included from C:\Users\Tom\Downloads\ArduinoRadio_v1.1\lcdRadio\lcdRadio.ino:4:0:

C:\Users\Tom\Documents\Arduino\libraries\Radio\src/radio.h:123:1: warning: ‘typedef’ was ignored in this declaration

};

^

C:\Users\Tom\Documents\Arduino\libraries\Radio\src/radio.h:132:1: warning: ‘typedef’ was ignored in this declaration

};

^

lcdRadio:49:1: error: ‘Radio’ does not name a type

Radio radio;

^

C:\Users\Tom\Downloads\ArduinoRadio_v1.1\lcdRadio\lcdRadio.ino: In function ‘void setup()’:

lcdRadio:71:7: error: ‘radio’ was not declared in this scope

if (!radio.init()) {

^

lcdRadio:79:3: error: ‘radio’ was not declared in this scope

radio.tuneTo(getEepromFreq());

^

lcdRadio:90:2: error: ‘radio’ was not declared in this scope

radio.setBassBoost(true);

^

C:\Users\Tom\Downloads\ArduinoRadio_v1.1\lcdRadio\lcdRadio.ino: In function ‘void loop()’:

lcdRadio:99:2: error: ‘radio’ was not declared in this scope

radio.updateStatus();

^

C:\Users\Tom\Downloads\ArduinoRadio_v1.1\lcdRadio\lcdRadio.ino: In function ‘void handleKeys()’:

lcdRadio:120:8: error: ‘radio’ was not declared in this scope

if (radio.state.volume < 15) {

^

lcdRadio:128:8: error: ‘radio’ was not declared in this scope

if (radio.state.volume > 0) {

^

lcdRadio:136:4: error: ‘radio’ was not declared in this scope

radio.seekDown();

^

C:\Users\Tom\Downloads\ArduinoRadio_v1.1\lcdRadio\lcdRadio.ino: In function ‘void updateDisplay()’:

lcdRadio:152:20: error: ‘radio’ was not declared in this scope

setEepromVolume(radio.state.volume);

^

lcdRadio:163:8: error: ‘radio’ was not declared in this scope

if (radio.state.hasStationName) {

^

lcdRadio:177:9: error: ‘radio’ was not declared in this scope

if (radio.state.volume > i * 2 + 1) {

^

C:\Users\Tom\Downloads\ArduinoRadio_v1.1\lcdRadio\lcdRadio.ino: In function ‘void drawStatusLine()’:

lcdRadio:198:12: error: ‘radio’ was not declared in this scope

lcd.print(radio.state.frequency);

^

Mehrere Bibliotheken wurden für “LiquidCrystal.h” gefunden
Benutzt: C:\Users\Tom\Downloads\arduino-1.8.7-windows\arduino-1.8.7\libraries\LiquidCrystal
Nicht benutzt: C:\Users\Tom\Documents\Arduino\libraries\Newliquidcrystal_1.3.5
Nicht benutzt: C:\Users\Tom\Documents\Arduino\libraries\NewliquidCrystal
exit status 1
‘Radio’ does not name a type

Ich komme da nicht weiter. Irgendein Denkanstoß ?

Du solltest Deine Bibliotheken aufräumen und uns einen Link zur Radio-Lib geben.

Gruß Tommy

was heißt "Aufräumen"??
Und Link zur "Radio-Lib" keine Ahnung.

Wahrscheinlich werde ich den "Arduino" irgendwann nur hassen.
Wie kann man Projekte ins Netz stellen die dann doch nicht funktionieren.

Übrigens findet der I2c-Scanner kein Display. Das nächste Problem.

Tom2Bit:
was heißt “Aufräumen”??
Und Link zur “Radio-Lib” keine Ahnung.

Wahrscheinlich werde ich den “Arduino” irgendwann nur hassen.
Wie kann man Projekte ins Netz stellen die dann doch nicht funktionieren.

Übrigens findet der I2c-Scanner kein Display. Das nächste Problem.

  1. solltest du dir die Fehlermeldungen mal genauer anschauen z.B.:
Mehrere Bibliotheken wurden für "LiquidCrystal.h" gefunden
Benutzt: C:\Users\Tom\Downloads\arduino-1.8.7-windows\arduino-1.8.7\libraries\LiquidCrystal
Nicht benutzt: C:\Users\Tom\Documents\Arduino\libraries\Newliquidcrystal_1.3.5
Nicht benutzt: C:\Users\Tom\Documents\Arduino\libraries\NewliquidCrystal

Das bedeutet Aufräumen ist angesagt.

  1. Befindet sich die Radio-Lib unter der von dir verlinkten Seite, hier als .zip.

  2. hast du nicht mal die neueste Version (Stand 2016) verwendet, wer weiß woher du die hast…
    Kleiner Vergleich zwischen deinem Sketch;

#include <radio.h>;

Und dem des Entwicklers:

#include "radio.h";

Also bitte nicht auf ein Projekt oder dem Entwickler schimpfen, wenn man selber Fehler eingebaut oder veraltete Dateien benutzt. :wink:

Tom2Bit:
.....
Übrigens findet der I2c-Scanner kein Display. Das nächste Problem.

Dann hast du vermutlich das Display falsch angeschlossen.

Und deine anderen Fehler wurden ja schon angesprochen.

C:\Users\Tom\Downloads\ArduinoRadio_v1.1\lcdRadio\lcdRadio.ino:4:19: warning: extra tokens at end of #include directive

#include <radio.h>;

#include “radio.h”;
#include “radio.h”

#include <radio.h>;
#include <radio.h>

combie:
#include “radio.h”;
#include “radio.h”

#include <radio.h>;
#include <radio.h>

Das komische Zeichen am Ende ist mir entgangen. :wink: Aber hier kann man dann doch mal auf den Entwickler schimpfen, steht auch so in der ino:

#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <Wire.h>
#include "radio.h";

Sketch kompiliert aber dennoch ohne Probleme, bzw. keine Fehler beim Codecheck.

Hi

So ein Entwickler ist auch nur ein Mensch - und glaube mir: Der hat den 'A*sch' deutlich höher, als das Groh hier.

Hier wird in jedem 2.ten Thread von delay() abgeraten - und trotzdem ist in JEDEM Beispiel delay() enthalten.
Warum?
Weil's in dem Beispiel eben nicht darauf ankommt, wie die Pause realisiert wird, sondern um die Funktion dieses einen Beispiel.
Trotzdem lernt dadurch der Anfänger, daß ÜBERALL delay() benutzt wird - und Das sogar in den super offiziellen Beispielen der Anbieter, Die Das ja gerade besser wissen müssten!!

Du siehst: Man kann viel interpretieren, mit Nachdenken/Hinterfragen kommt ggf. aber was ganz Anderes heraus.
Und bei Deinem Fehler - wenn der Sketch TROTZ dieses Fehler kompiliert - was willst Du mehr? Du hast ein funktionierendes Beispiel - MEHR, als wir hier - in der Regel - hingeworfen bekommen.

MfG

Sketch kompiliert aber dennoch ohne Probleme, bzw. keine Fehler beim Codecheck.

Nöö…
Die Warnung habe ich doch mit kopiert.

Tipp:
Eine Warnung, ist meist ein Fehler, der bei dir noch keine Auswirkungen hatte.
Aber das wird noch.

Abhilfe:
Die Sprache lernen, welche man benutzen möchte.
Aufmerksamkeit hoch halten.


Aber hier kann man dann doch mal auf den Entwickler schimpfen, steht auch so in der ino:

Solange einem sowas durch die Lappen geht, DARF man nicht die Schuld bei anderen suchen. Denn dann lernt man genau das falsche. Es verhindert wirksam die eigene Weiterentwicklung.


Hier wird in jedem 2.ten Thread von delay() abgeraten - und trotzdem ist in JEDEM Beispiel delay() enthalten.
Warum?

Trotzdem lernt dadurch der Anfänger, daß ÜBERALL delay() benutzt wird - und Das sogar in den super offiziellen Beispielen der Anbieter,

Der “Anfänger” wird Erfahrungen machen müssen, um diesen Anfängerstatus verlassen zu können.
Dazu gehört auch die Beurteilungsfähigkeit, wann ein Delay störend ist, und wann es durchaus nutzbar ist.

Ich persönlich halte nichts von einem sturen Anit-Delay oder Anti-Goto Dogmatismus.

Denn:
Jedes Sprachmittel/Funktion, kann man so ungeschickt einsetzen, so dass es Probleme verursacht.
Der ungeschickte Einsatz, ist ein ungeschickter Einsatz, mehr nicht.
Mit jedem Sprachmittel kann man sich eine Frikadelle ans Knie nageln. :o

Grundsätzlich:
Es gibt keine bösen Sprachmittel/Funktionen.


Man sollte sein Denken einschalten, und auch trainieren.
Ja, das ist ein Prozess, welcher einiges an Zeit beansprucht.
Und auch viel Übung.
Ja, es wird Jahre in Anspruch nehmen!

combie:
Nöö…
Die Warnung habe ich doch mit kopiert.

Tipp:
Eine Warnung, ist meist ein Fehler, der bei dir noch keine Auswirkungen hatte.
Aber das wird noch.

War auch mein Fehler, da ich die Arduino IDE nur selten nutze, hatte ich die Compiler-Fehlermeldungen noch auf Standard stehen. Ich arbeite mit Platformio über VSC, mit IntelliSense und dort würden die Fehler und Warnungen direkt angezeigt.

Abhilfe:
Die Sprache lernen, welche man benutzen möchte.
Aufmerksamkeit hoch halten.

Ich bin dran, hab nur leider nicht die Zeit das intensiv zu lernen, daher brauche ich manchmal auch was länger, aber gebe nicht so einfach auf.

Solange einem sowas durch die Lappen geht, DARF man nicht die Schuld bei anderen suchen. Denn dann lernt man genau das falsche. Es verhindert wirksam die eigene Weiterentwicklung.

Ich wusste das ich mit meinem Spruch “Mecker” kriege, ich schreib manchmal unüberlegt, aber du hast recht. Man sollte einem Sketch von irgendeiner Seite auch nicht blind auf Funktion vertrauen, sondern den Code lesen und nach Möglichkeit verstehen.

so,

ich habe erst einmal alles gemacht was mir hier empfohlen wurde.

Und siehe da es geht schon mal der Sketch ohne Fehlermeldungen und das Display ist auch o.k.

Jetzt muss ich nur noch den Rest verdrahten.

Für´s Erste mal vielen Dank.

Nun bin ich doch wieder in einer Sackgasse.

Beim kompilieren der Sketches (1. Post) und auch beim Hochladen bekomme ich keine Fehlermeldung. Jedoch erscheint auf dem Display "Radio?" und "Radio error!"

Das RDA5807 (FM-Radio) ist angeschlossen. Aber auch ohne diesen RDA5807 habe ich die Fehlermeldung auf dem Display.

Das RDA5807 (FM-Radio) ist angeschlossen. Aber auch ohne diesen RDA5807 habe ich die Fehlermeldung auf dem Display.

Findet der I2C Scanner das Radio?

Die I2C Anbindung, in dem Schaltplan, aus deinem eingangs genannten Artikel, ist aus meiner Sicht eine Unmöglichkeit.
Verwende einen besseren Levelschifter.

Sorge für allseits ausreichende Pullup.

Sorry, ich habe SDA und SCL vertauscht.
Nun funktioniert auch das Radio.

Frage mich nun noch ob die im Link (1.Post) dargestellte Beschaltung am Audio-Ausgang des RDA5807 notwendig ist.

Zwischen RDA5807 und UNO wird ein Levelshifter benötigt.

z.B. ein solcher

combie:
Zwischen RDA5807 und UNO wird ein Levelshifter benötigt.

z.B. ein solcher

Das ist mir klar. werde ich mir besorgen. Trotzdem funktioniert das erst einmal auch so.

?? Nur habe ich nun festgestellt das bis auf die "Right" Taste keine andere reagiert. Normalerweise sollte die Taste "Left" für den Sendersuchlauf zurück sein und Die "Up" und "Down" Taste für die Lautstärke.
Da funktioniert irgendwie was nicht.

Das wundert mich nicht.
Die Tastenabfrage ist da ja auch wirklich dämlich gelöst.

Beim leichtesten Seitenwind geht da nichts mehr.

Naja , bei meinen letzten Projekt habe ich die Tasten nicht mit auf dem LCD-Board gehabt. Da hatte ich die Tasten-abfrage über die Pin´s des Arduino.
Das jetzt ist nun wieder Neuland für mich.

Irgendeine Idee oder Denkanstoß wie ich das lösen kann?

Irgendeine Idee oder Denkanstoß wie ich das lösen kann?

Klar, weiß ich genau, wie ich das angehen könnte/würde.
Aber das Problem ist so trivial, dass auch du das schaffen kannst.

Das jetzt ist nun wieder Neuland für mich.

Für den Schreiber des Tutoroials offensichtlich auch.

Der hat da nicht drüber nachgedacht.
Und du scheinst das auch nicht wirklich zu wollen/können.

--
Warum ich dir nicht helfe?
Ich befürchte dass ich meine Lebensenergie sinnlos verplempere, wenn ich dir das vorkaue.

--

Also hier mal eine uralte chinesische Weisheit für dich:

Oftmals gibt es 3 Wege, welche zum Ziel führen:

Der goldene Weg
Problem erkennen
Problem analysieren
Lösung erarbeiten
Lösung durchsetzen

Der silberne Weg
Abschauen, genauso machen wie die anderen.
(und hier schaut man nicht beim Dümmsten nach, sondern in die Anleitungen des Herstellers)

Der bronzene Weg
Aus Erfahrung lernen.
(hier kann man dann auch noch zusätzlich den relaxten Umgang mit Leid und Schmerz lernen)

Alternativen
Keine, nur das Versagen.

Danke für die Beiträge.
Aber nach gut 3 Stunden bin ich nicht weiter gekommen.

Sorry aber ich komme nicht weiter.