Themabewertung:
  • 1 Bewertung(en) - 5 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
ESP32 Webradio Platine Version 1.1
#41
(26.02.2021, 15:42)Bernhard45 schrieb: Hallo Bernhard45,
danke für den Hinweis mal in den source code zu schauen. Das ist sicher sinnvoller als mit der HW "rumzuexperimentieren". Da muss ich mich jetzt mal reindenken und die richtigen Stellen für debug-Ausgaben finden. Ich bin seit Kurzem auf VScode/platformIO umgestiegen und noch nicht "sattelfest". Werde es, so wie von dir vorgeschlagen, mal mit DEBUG versuchen - ist auch Neuland für mich.

Gruß Jochen
Zitieren
#42
Hallo Bernhard45,
Ich sehe dass auch meine nicht funktionierenden IR Fernbedienungen zumindest es in die isr_IR routine schaffen, dann aber abgeschmettert werden. Wieso? In der isr_IR interrupt routine wollte ich mir einige Werte ausgeben lassen scheitere aber am dbgprint(...)
So wie ich es verwende werden nur strings (?Strings?) ausgegeben es klappt also in der Form
dbgprint("IR interval ok ");
nicht aber so:
dbgprint(intval);
und auch nicht so:
#include <string>
dbgprint(to_string(ir_loccount));
Beim googlen nach dbgprint bekomme ich nur Antworten zu Dbgprint was ja wohl was anderes ist.

Kannst du mir bitte einen Tipp geben. Vielen Dank!
Zitieren
#43
(27.02.2021, 11:50)MHz000 schrieb: Beim googlen nach dbgprint bekomme ich nur Antworten zu Dbgprint was ja wohl was anderes ist.

Kannst du mir bitte einen Tipp geben. Vielen Dank!

Hallo,

googlen brauchst Du gar nicht, die Funktion dbgprint stammt vom Autor des ESP32Radios selbst, in main.cpp findet man die Deklaration und Definition:

PHP-Code:
//**************************************************************************************************
//                                          D B G P R I N T                                        *
//**************************************************************************************************
// Send a line of info to serial output.  Works like vsprintf(), but checks the DEBUG flag.        *
// Print only if DEBUG flag is true.  Always returns the formatted string.                         *
//**************************************************************************************************
chardbgprint ( const charformat, ... )
{
 
 static char sbuf[DEBUG_BUFFER_SIZE] ;                // For debug lines
 
 va_list varArgs                                    // For variable number of params

 
 va_start varArgsformat ) ;                       // Prepare parameters
 
 vsnprintf sbufsizeof(sbuf), formatvarArgs ) ;  // Format the message
 
 va_end varArgs ) ;                                 // End of using parameters
 
 if DEBUG                                         // DEBUG on?
 
 {
 
   Serial.print ( "D: " ) ;                           // Yes, print prefix
 
   Serial.println sbuf ) ;                          // and the info
 
 }
 
 return sbuf                                        // Return stored string


Die Anwendung dieser Funktion ist eigentlich sehr logisch, ich zitiere hier mal zwei Aufrufe aus dem Quellcode des Radios:

PHP-Code:
// print the list of networks seen:
 
 dbgprint "Number of available networks: %d",numSsid ) ; 

und

PHP-Code:
 dbgprint "%2d - %-25s Signal: %3d dBm, Encryption %4s, %s",
 
              i 1WiFi.SSID(i).c_str(), WiFi.RSSI(i),
 
              getEncryptionType encryption ),
 
              acceptable ) ; 

Durchschaut?  Du kannst also einfach eine Zeichenkette ausgeben, aber auch eine beliebige Liste von Variablen, die durch einen Formatstring sogar noch zurechtgestutzt werden kann.

Wenn es der Empfänger bis in die isr_IR() schafft, ist das ja schon mal was. Warum kommt es dennoch nicht zur Anzeige eines rawcodes auch wenn wir ein Debugbuild haben? Nun schauen wir uns die Sache mal an.

Die Ausgabe des rawcodes wird ja in der scanIR()-Funktion erledigt, hier nochmal der Quellecode der scanIR():

Code:
//**************************************************************************************************
//                                     S C A N I R                                                 *
//**************************************************************************************************
// See if IR input is available.  Execute the programmed command.                                  *
//**************************************************************************************************
void scanIR()
{
 char        mykey[20] ;                                   // For numerated key
 String      val ;                                         // Contents of preference entry
 const char* reply ;                                       // Result of analyzeCmd

 if ( ir_value )                                           // Any input?
 {
   sprintf ( mykey, "ir_%04X", ir_value ) ;                // Form key in preferences
   if ( nvssearch ( mykey ) )
   {
     val = nvsgetstr ( mykey ) ;                           // Get the contents
     dbgprint ( "IR code %04X received. Will execute %s",
                ir_value, val.c_str() ) ;
     reply = analyzeCmd ( val.c_str() ) ;                  // Analyze command and handle it
     dbgprint ( reply ) ;                                  // Result for debugging
   }
   else
   {
     dbgprint ( "IR code %04X received, but not found in preferences!  Timing %d/%d",
                ir_value, ir_0, ir_1 ) ;
   }
   ir_value = 0 ;                                          // Reset IR code received
 }
}

Damit wir überhaupt in den Codebereich kommen, wo eine Ausgabe erzeugt wird, müssen wir an

if ( ir_value )                                           // Any input?

vorbei. Das passiert wenn ir_value true/wahr ist, also einen Wert ungleich 0 annimmt. Anmerkung: Wir sehen ja auch das ir_value nach Durchlauf immer wieder auf 0 gesetzt wird.

Wo wird die globale Variable ir_value also auf true gesetzt? Klar, in der Interrupt Service Routine isr_IR(), also da wo Du  mit deinem Empfänger schon reinkommst. Schauen wir uns den Quellcode der isr_IR() nochmal an:

Code:
void IRAM_ATTR isr_IR()
{
 sv uint32_t      t0 = 0 ;                          // To get the interval
 sv uint32_t      ir_locvalue = 0 ;                 // IR code
 sv int           ir_loccount = 0 ;                 // Length of code
 uint32_t         t1, intval ;                      // Current time and interval since last change
 uint32_t         mask_in = 2 ;                     // Mask input for conversion
 uint16_t         mask_out = 1 ;                    // Mask output for conversion

 t1 = micros() ;                                    // Get current time
 intval = t1 - t0 ;                                 // Compute interval
 t0 = t1 ;                                          // Save for next compare
 if ( ( intval > 300 ) && ( intval < 800 ) )        // Short pulse?
 {
   ir_locvalue = ir_locvalue << 1 ;                 // Shift in a "zero" bit
   ir_loccount++ ;                                  // Count number of received bits
   ir_0 = ( ir_0 * 3 + intval ) / 4 ;               // Compute average durartion of a short pulse
 }
 else if ( ( intval > 1400 ) && ( intval < 1900 ) ) // Long pulse?
 {
   ir_locvalue = ( ir_locvalue << 1 ) + 1 ;         // Shift in a "one" bit
   ir_loccount++ ;                                  // Count number of received bits
   ir_1 = ( ir_1 * 3 + intval ) / 4 ;               // Compute average durartion of a short pulse
 }
 else if ( ir_loccount == 65 )                      // Value is correct after 65 level changes
 {
   while ( mask_in )                                // Convert 32 bits to 16 bits
   {
     if ( ir_locvalue & mask_in )                   // Bit set in pattern?
     {
       ir_value |= mask_out ;                       // Set set bit in result
     }
     mask_in <<= 2 ;                                // Shift input mask 2 positions
     mask_out <<= 1 ;                               // Shift output mask 1 position
   }
   ir_loccount = 0 ;                                // Ready for next input
 }
 else
 {
   ir_locvalue = 0 ;                                // Reset decoding
   ir_loccount = 0 ;
 }
}

ir_value wird hier in diesem Teil gesetzt, wenn folgende Bedingungen wahr sind:


Code:
else if ( ir_loccount == 65 )                      // Value is correct after 65 level changes
 {
   while ( mask_in )                                // Convert 32 bits to 16 bits
   {
     if ( ir_locvalue & mask_in )                   // Bit set in pattern?
     {
       ir_value |= mask_out ;                       // Set set bit in result


ir_loccount muss also 65 sein, es muss also ein IR-Code mit der Länge von 65 bit empfangen wurden sein. Ist das der Fall? Stimmen die Zeiten für die Low/High-Pulse, so dass ir_loccount überhaupt incrementiert wird? Passen die Pulszeiten der Fernbedienung überhaupt zum Quellcode oder müssen die Pulszeiten vielleicht für das von deiner Fernbedienung benutzte Protokoll angepasst werden? Es gibt da ja haufenweise Protokolle die von Fernbedienungen "gesprochen" werden, hier eine Übersicht: https://www.mikrocontroller.net/articles/IRMP

Erst wenn das alles passt, wird ein Flag gesetzt und scanIR erzeugt eine Ausgabe eines rawcodes deiner Fernbedienung auf der seriellen Schnittstelle bzw. Console.

Viele Grüße
B45
Ansprechpartner für Umbau oder Modernisierung von Röhrenradios mittels SDR,DAB+,Internetradio,Firmwareentwicklung. 
Unser Open-Source Softwarebaukasten für Internetradios gibt es auf der Github-Seite! Projekt: BM45/iRadio (Google "github BM45/iRadio")
Zitieren
#44
Hi Bernhard45,
wow, da hast du dir aber wirklich viel Mühe gemacht und mir Zeit geschenkt.Vielen Dank dafür!
Wenn ich das richtig sehe, dann folgt dbgprint exakt dem printf Format, war ein sehr hilfreicher Tipp.
Beim rumfummeln im source code ... na ja, ich habe die Quelle komplett neu übersetz und siehe da:
ich bekomme von einer meiner LED-remote controls Einträge im serial monitor zu sehen wie diesen hier:
D: IR code 629D received, but not found in preferences! Timing 585/1640
Da werde ich wohl nur noch die Zuordnung von 629D etc. zu den gewünschten Radio-Funktionen machen müssen.
(soweit habe ich die Doku defaultprefs.h:
# Some IR codes
ir_40BF = upvolume = 2
ir_C03F = downvolume = 2
noch nicht verinnerlicht, vielleicht beschleunigt ein Tipp, z.B. für stream up/down, das weitere Vorgehen :-) )

Wenn das geschafft ist wirds kniffelig: vor mir liegt eine minimalistischer IR-remotecontroler mit nur 7 Tasten, der völlig ausreichend für die Radio Steuerung wäre: VOL +/-, Sender Up/down und mute, da bleiben immernoch 2 übrig.
Aber Eins nach dem Anderen.

Gruß Jochen
Zitieren
#45
die Anweisungen sind in der defaultprefs.h ersichtlich

uppreset = 1 wechselt auf den nächsten Programmplatz (die umgekehrte Richtung kann dann nur downpreset sein)
upvolume = 2 erhöht die Lautstärke um 2%
downvolume = 2 verringert die Lautstärke um 2%
stop stoppt die Wiedergabe
resume greift die Wiedergabe wieder auf
station = icecast.omroep.nl:80/radio1-bb-mp3 spielt einen Sender ausserhalb der playlist

also wird von der FB so der preset-Zähler um 1 erhöht:

ir_40BF = uppreset = 1

Achte darauf dass in der Konfigurationsdatei keine Zeile auskommentiert werden kann. Was nicht gebraucht wird muss gelöscht werden (so meine Erfahrung)
Gruß,
Jupp
-----------------------------
"Normal" ist auch nur eine Einstellung auf der Waschmaschine
(Whoopi Goldberg)
Zitieren
#46
Guten Morgen Jupp,
Du hast den Nagel auf den Kopf getroffen! So wie von dir beschrieben funktioniert es. Jetzt sehe ich auch die Kommando key words in der index_html.h.
Die nächste Baustelle:
“pin_shutdown” is the pin that will be set if the radio is not playing or the volume is set to zero. This output-pin can be used to shut down the amplifier.
Mal sehen ob ich das hin bekomme. Und dann wäre ja noch die Anpassung an die minimalistische IR-Fernbedinung mit nur wenigen Knöpfen, Bernhard45 hat ja schon Hinweise gegeben.
Es bleibt spannend.
Gruß Jochen
Zitieren
#47
Das mit dem shutdown des externen Amplifier scheint nicht ganz so einfach zu sein. GPIO34/35 sind, so habe ich es jetzt gelernt, nur als Input zu verwenden (HW-Limitation) und 12/13, so vermute ich, sind wohl auf dem Modul mit dem USB/UART verbunden, also auch nicht zu verwenden.
Vielleicht kann man den Nextion Anschluß dafür verwenden. Vorteil wäre, es ist auf Jupps Platine mit GND und 5V vorhanden. ABER: in main.cpp kann man nur: "Define (just one) type of display. See documentation" ein display Anschluß aktivieren (gleiches gilt für das TFT display). Muß ich mal testen.
Frage an die community: hat einer von euch Erfahrung mit dem shutdown-Anschluß?
Gruß Jochen
Zitieren
#48
Erfolg!
Der Nextion TX-Anschluß läßt sich zur Steuerung eines externen Amplifier verwenden.
Nur: pin_shutdown = 17 # GPIO Pin number external pwr shutdown #17 TX2
auf der Control page des Web-interfaces eintragen, das war es schon.
(un)MUTE oder Vol auf 0 runterdrehen und schon schaltet pin_17 zwischen 0 und 3,3V
Aber Vorsicht: das ist ein direkter Prozessor_pin.

Jupp. falls mal eine Platinen-Version 2.0 fällig wird, bitte eine kleine Pufferstufe vorsehen.
Zitieren
#49
Hallo Jochen,
ich wüsste nicht dass gpio17 eine Sonderstellung hätte. Natürlich wäre es eleganter ALLE gpios zu puffern und auch gegen Überspannung abzusichern. Aber auch viel Aufwand. Es wird ja nicht direkt eine hohe Leistung geschaltet, sonder es ist ein Relais mit Optokoppler oder ein MOSFET-Schalter oder auch nur ein einfacher Transistor dazwischen.

ESP32 Pinout Reference
Gruß,
Jupp
-----------------------------
"Normal" ist auch nur eine Einstellung auf der Waschmaschine
(Whoopi Goldberg)
Zitieren
#50
Hallo Jupp,
all meine interessanten WEB-pages hatte ich in Firefox/Pocket gespeichert ... und jetzt komme ich nicht mehr ran - Error 502. Hoffentlich finde ich eine Möglichkeit die wieder zu aktivieren. Deine Adresse fand ich zum Glück bei den Email Kontakten.
Ich war selber überrascht, das es bei denGPIOs herbe Einschränkungen gibt. Die Tabelle
https://drive.google.com/file/d/1gbKM7DA...E2TPZ/view
legt Details offen. Eine freundliche userein hat sie mir gepostet.
Für den IR_receiver benutze ich nun pin_ir = 16 # ex Tx2 Nextion Pin for IR receiver VS1838B mit etwas externe Beschaltung. Um den externen Amplifier zu schalten werde ich GPIO 17 verwenden, warte noch auf ein SSR und ein open frame Netzteil.
Ach ja, mit deinen außerordentlichen Gehäusen kann ich nicht mithalten, meine Lösung für das Gehäuse besteht in einem hölzernen Karteikasten. Na ja, viel Platz darin und der passt ins Regal mit dem Verstärker.
Bleb gesund und beste Grüße
Jochen
Zitieren
#51
(19.02.2021, 22:39)saarfranzose schrieb: Ivan, du kannst es auch bei einem fertigen Radio ändern. Es muss dazu nicht geöffnet werden. Nur im webinterface die Änderungen wie beschrieben eintragen.

Hallo, Jupp, gerade ausprobiert. Über Web-Interface kann man problemlos die Änderungen durchführen. Funktioniert prima, Danke!
Gruß!
Ivan
Zitieren


Möglicherweise verwandte Themen...
Thema Verfasser Antworten Ansichten Letzter Beitrag
  Brand-Radio mit ESP32 saarfranzose 17 822 20.02.2021, 20:12
Letzter Beitrag: saarfranzose
  Nordmende 500-10 mit ESP32 saarfranzose 7 639 22.11.2020, 12:36
Letzter Beitrag: saarfranzose
  Skull-Radio mit ESP32 und Edzelf-Software saarfranzose 20 2.594 17.06.2020, 10:18
Letzter Beitrag: saarfranzose
  Webradio in altem Gewand Pinsel 7 1.379 10.10.2019, 12:59
Letzter Beitrag: saarfranzose

Gehe zu: