Hallo Leute, mal kurz zu meinem Projekt aktuell: Mein Ziel ist es, ein Radio zu bauen. Es soll FM Empfangen können (mit RDS). Dazu Bluetooth Audio und Aux Anschluss mit 2*15 Watt Ausgangsleistung. Bedienbar über einen Rotary und ein LCD Display. Ich habe als Grundlage einen Arduino, dem ich einen eigenen Header verpasst habe. Auf dem Header ist folgendes: -DS1307 Uhrzeit-IC -I2C Levelshifter -Levelshifter für LCD Display -ws2812 LED -Header für LCD, Rotary, usw. -Header für Brücke zur Audioplatine Auf der Audioplatine sind folgende Sachen: -TPA3140D2 Class-D AMP IC von TI -TDA7439 Analoger Audio Prozessor von ST, angebunden an I2C -XS3868 Bluetooth-Modul, angebunden an Arduino über Uart -Si4703 Breakout-Board, angebunden an Arduino über I2C Im Prinzip funktioniert alles, aber auch nichts. Was bisher ohne Probleme funktioniert ist der Verstärker, der Audioprozessor, das Display und der Rotaryencoder sowie der Button. Radio hören über den Si4703 kann ich im Prinzip, allerdings ist der Empfang extremst schlecht (empfange einen einzigsten Sender draußen im Freien damit, dafür funktioniert aber dort auch der RDS Empfang). Das Bluetooth Modul funktioniert und funktioniert mal nicht. Es ist mehr oder weniger Zufall ob das XS3868 Modul via Bluetooth sichtbar ist. Wenn es sichtbar ist, funktioniert es, wenn nicht dann kann man sich halt auch nicht darauf verbinden. Das DS1307 Modul funktioniert im Prinzip auch, allerdings liefert es falsche Werte zurück sobald die Audioplatine angeschlossen ist. I2C Adressen überschneiden sich keine, da habe ich nachgesehen. Außerdem kommt es mir so vor als ob der Arduino wilde und unkontrollierte Programmsprünge macht. Er führt z.B. gelegentlich die Routine aus um einen neuen Sender zu suchen obwohl er das nicht soll. Kann es sein dass es da zu Problemen kommt aber einer gewissen Tiefe an verschachtelten Funktionsaufrufen? Bilder und Schaltpläne habe ich angehängt, ich hoffe ihr habt ein paar Ideen oder könnt mir ein paar Tipps bei der Fehlersuche geben. Danke & Gruß Markus
Mh mal kurzes Update: Das Problem mit dem DS1307 konnte ich dadurch lösen dass ich das Brückenkabel auf 1/3 der Größe reduziert habe. Seitdem läuft das Auslesen der Uhrzeit korrekt. Was das XS3868 angeht: Ich habe herausgefunden, dass wenn die Verbindung zum Arduino Shield besteht via Brückenkabel funktioniert es problemlos. Kann dann via provisorisch angelötetem USB-FTDI mit ihm kommunizieren. Sobald das Brückenkabel drauf ist, startet er nur manchmal, scheint also mit der Anbindung zum Shield zusammenzuhängen. Habe die Uart Pegel mit dem Oszi mal durchkontrolliert, aber da waren keine Auffälligkeiten.
Wenn der Radioempfang schlecht ist, würde ich zuerst die Stromversorgung und dann die Antenne überprüfen. Generell ist es schwierig, einen Mikrocontrolelr oder andere getaktete Schaltungen in unmittelbarer Nähe zu einem Radioempfänger zu betreiben. Eventuell wirst du da abschirmen müssen, wie es auch viele Handies und Taschenradios tun.
1 | #include <EEPROM.h> |
2 | #include <Si4703_Breakout.h> |
3 | #include <Wire.h> |
4 | #include <DS1307new.h> |
5 | #include <Adafruit_NeoPixel.h> |
6 | #include <stdint.h> |
7 | #include <stdlib.h> |
8 | #include <TFTv2.h> |
9 | #include <SPI.h> |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | //Led
|
16 | Adafruit_NeoPixel led = Adafruit_NeoPixel(1, 8, NEO_GRB + NEO_KHZ800); |
17 | |
18 | //Clock
|
19 | DS1307new clock; |
20 | char HourChars[5], MinuteChars[5], SecondChars[5]; |
21 | unsigned long LastTimeUpdate = 0; |
22 | unsigned int LastHour=100, LastMinute=100, LastSecond=100; |
23 | |
24 | //Radio
|
25 | Si4703_Breakout FmTuner(A0,A4,A5); |
26 | int Frequency=0, Volume = 10, VolumeUpDown=0; |
27 | char FrequencyChars[8]; |
28 | int FrequencyChangeWished, VolumeChangeWished; |
29 | int SeekButtonPressed=0, SeekWished=0; |
30 | char RDS[9] = {" "}; |
31 | char RDSOld[9] = {" "}; |
32 | |
33 | //SystemState
|
34 | int SystemState=0, SystemStateChangeWished=0; |
35 | |
36 | //Rotary
|
37 | int RotaryButtonPressed=0; |
38 | |
39 | |
40 | |
41 | |
42 | void setup() |
43 | {
|
44 | |
45 | //TDA7439 Test
|
46 | // Wire.begin();
|
47 | // Wire.beginTransmission(68);
|
48 | // Wire.write(0x10);
|
49 | |
50 | // Wire.write(0x03);
|
51 | // Wire.write(0x00);
|
52 | // Wire.write(0x00);
|
53 | //Bass
|
54 | // Wire.write(0x07);
|
55 | // Wire.write(0x07);
|
56 | // Wire.write(0x07);
|
57 | |
58 | // Wire.write(0x00);
|
59 | // Wire.write(0x00);
|
60 | // Wire.endTransmission();
|
61 | |
62 | |
63 | //Init TFT
|
64 | TFT_BL_ON; |
65 | |
66 | //LCD PWM
|
67 | pinMode(10, OUTPUT); |
68 | analogWrite(10, 255); |
69 | |
70 | Tft.TFTinit(); |
71 | Tft.fillScreen(221,239,0, 319,YELLOW); |
72 | |
73 | //Init LED
|
74 | led.begin(); |
75 | led.show(); |
76 | led.setPixelColor(0, 50, 0, 0); |
77 | led.show(); |
78 | |
79 | |
80 | |
81 | |
82 | Serial.begin(115200); |
83 | Serial.write("Start \n"); |
84 | |
85 | //RotaryButton
|
86 | pinMode(7, INPUT); |
87 | digitalWrite(7,HIGH); |
88 | |
89 | //Button
|
90 | pinMode(12, INPUT); |
91 | digitalWrite(12,HIGH); |
92 | |
93 | //Rotary
|
94 | pinMode(2, INPUT); |
95 | digitalWrite(2, HIGH); |
96 | pinMode(3, INPUT); |
97 | digitalWrite(3, HIGH); |
98 | attachInterrupt(0, doEncoder, CHANGE); |
99 | |
100 | |
101 | |
102 | |
103 | |
104 | |
105 | //Init Radio
|
106 | FmTuner.powerOn(); |
107 | FmTuner.setChannel(1030); |
108 | FmTuner.setVolume(15); |
109 | FmTuner.AmpOff(); |
110 | |
111 | |
112 | |
113 | |
114 | |
115 | }
|
116 | |
117 | |
118 | |
119 | void loop() |
120 | {
|
121 | |
122 | if (digitalRead(7) == LOW && RotaryButtonPressed==0) { |
123 | Serial.write("rot pressed \n"); |
124 | RotaryButtonPressed=1; |
125 | SystemStateChangeWished=1; |
126 | |
127 | }
|
128 | else if (RotaryButtonPressed==1 && digitalRead(7) == HIGH) { |
129 | RotaryButtonPressed=0; |
130 | }
|
131 | |
132 | else if (digitalRead(12) == LOW && SeekButtonPressed==0) { |
133 | Serial.write("seek pressed \n"); |
134 | SeekButtonPressed=1; |
135 | SeekWished=1; |
136 | |
137 | }
|
138 | else if (SeekButtonPressed==1 && digitalRead(12) == HIGH) { |
139 | SeekButtonPressed=0; |
140 | }
|
141 | |
142 | DoLoopStuff(); |
143 | DoTime(); |
144 | |
145 | |
146 | }
|
147 | void DoLoopStuff() { |
148 | |
149 | if (SystemState==0 && SystemStateChangeWished==1) { |
150 | |
151 | Serial.write("get on \n"); |
152 | SystemState=1; |
153 | SystemStateChangeWished=0; |
154 | |
155 | //PowerUp
|
156 | FmTuner.setVolume(Volume); |
157 | led.setPixelColor(0, 0, 50, 0); |
158 | led.show(); |
159 | |
160 | //Draw all Important
|
161 | Tft.fillScreen(); |
162 | |
163 | //Draw Volume
|
164 | Tft.drawLine(220,0,220,319,YELLOW); |
165 | Tft.fillScreen(221,239,0, 319,0x0000); |
166 | if (Volume==15) Tft.fillScreen(221,239,0, 319,YELLOW); |
167 | else Tft.fillScreen(221,239,319, 319-(Volume*21),YELLOW); |
168 | |
169 | //Draw Frequency
|
170 | DrawFrequency(); |
171 | }
|
172 | |
173 | if (SystemState==1) { |
174 | |
175 | if (SystemStateChangeWished==1) { |
176 | |
177 | Serial.write("get off pressed \n"); |
178 | |
179 | //PowerDown
|
180 | SystemState = 0; |
181 | SystemStateChangeWished=0; |
182 | //TurnOff FmTuner
|
183 | FmTuner.setVolume(0); |
184 | FmTuner.setChannel(Frequency); |
185 | |
186 | //LedToRed
|
187 | led.setPixelColor(0,50,0,0); |
188 | led.show(); |
189 | |
190 | //DeleteScreen and ForceClockUpdate
|
191 | Tft.fillScreen(); |
192 | LastHour=110; |
193 | LastMinute=100; |
194 | LastSecond=100; |
195 | |
196 | //Save Frequency
|
197 | int tmpFrequency = Frequency; |
198 | for (int i=0;i<5;i++) { |
199 | |
200 | if (tmpFrequency > 255) { |
201 | EEPROM.update(i, 255); |
202 | tmpFrequency -= 255; |
203 | }
|
204 | else if (tmpFrequency >0 && tmpFrequency<=255) { |
205 | EEPROM.write(i,tmpFrequency); |
206 | tmpFrequency = 0; |
207 | }
|
208 | else EEPROM.write(i,0); |
209 | |
210 | }
|
211 | }
|
212 | |
213 | if (VolumeChangeWished == 1) { |
214 | VolumeChangeWished = 0; |
215 | FmTuner.setVolume(Volume); |
216 | |
217 | if (VolumeUpDown == 1) { |
218 | if (Volume==15) Tft.fillScreen(221,239,0, 319,YELLOW); |
219 | else Tft.fillScreen(221,239,319, 319-(Volume*21),YELLOW); |
220 | }
|
221 | else if (VolumeUpDown == -1) { |
222 | if (Volume==0) Tft.fillScreen(221,239,0, 319,0x0000); |
223 | else Tft.fillScreen(221,239,0, (15-Volume)*21,0x0000); |
224 | }
|
225 | |
226 | |
227 | |
228 | |
229 | |
230 | }
|
231 | |
232 | if (SeekWished==1) { |
233 | SeekWished=0; |
234 | Serial.write("neue freq \n"); |
235 | //Frequency = FmTuner.seekUp();
|
236 | DrawFrequency(); |
237 | |
238 | }
|
239 | |
240 | DrawRDS(); |
241 | |
242 | |
243 | }
|
244 | }
|
245 | |
246 | |
247 | void DrawFrequency() { |
248 | |
249 | sprintf(FrequencyChars,"%d.%d",Frequency/10,Frequency%10); |
250 | Tft.fillScreen(175,219,60, 230,0x0000); |
251 | Tft.drawString(FrequencyChars,180, 190,4,YELLOW); |
252 | |
253 | }
|
254 | |
255 | void DrawRDS() { |
256 | FmTuner.readRDS(RDS); |
257 | |
258 | |
259 | //check if RDS changed
|
260 | int changed=0; |
261 | for (int i=0; i<9 ; i++) { |
262 | if (RDS[i] != RDSOld[i]) changed=1; |
263 | }
|
264 | |
265 | if (changed==1) { |
266 | |
267 | //Copy Message
|
268 | for (int i=0; i<9; i++) { |
269 | RDSOld[i]=RDS[i]; |
270 | }
|
271 | |
272 | Tft.fillScreen(100,150,15, 310,0x0000); |
273 | Tft.drawString(RDS,100, 255,6,YELLOW); |
274 | Serial.println(RDS); |
275 | |
276 | |
277 | }
|
278 | |
279 | }
|
280 | void DoTime() { |
281 | |
282 | if (millis() > LastTimeUpdate+1000) { |
283 | |
284 | LastTimeUpdate=millis(); |
285 | clock.getTime(); |
286 | |
287 | |
288 | |
289 | if (LastHour != clock.hour) { |
290 | |
291 | if (clock.hour < 10) sprintf(HourChars,"0%d:",clock.hour); |
292 | else if (clock.hour >= 10 && clock.hour <= 24) sprintf(HourChars,"%d:",clock.hour); |
293 | Serial.write(HourChars); |
294 | |
295 | if (SystemState==1) { |
296 | |
297 | }
|
298 | else { |
299 | Tft.fillScreen(100,145,230, 300,0x0000); |
300 | Tft.drawString(HourChars,100, 250,6,YELLOW); |
301 | |
302 | }
|
303 | }
|
304 | |
305 | if (LastMinute != clock.minute) { |
306 | |
307 | if (clock.minute < 10) sprintf(MinuteChars,"0%d:",clock.minute); |
308 | else if (clock.minute >=10 && clock.minute <= 60) sprintf(MinuteChars,"%d:",clock.minute); |
309 | |
310 | if (SystemState==1) { |
311 | |
312 | }
|
313 | else { |
314 | Tft.fillScreen(100,145,130, 200,0x0000); |
315 | Tft.drawString(MinuteChars,100, 150,6,YELLOW); |
316 | |
317 | }
|
318 | |
319 | }
|
320 | |
321 | if (LastSecond != clock.second) { |
322 | |
323 | if (clock.second < 10) sprintf(SecondChars,"0%d",clock.second); |
324 | else if (clock.second >= 10 && clock.second <=60) sprintf(SecondChars,"%d",clock.second); |
325 | |
326 | if (SystemState==1) { |
327 | |
328 | }
|
329 | else { |
330 | Tft.fillScreen(100,145,30, 100,0x0000); |
331 | Tft.drawString(SecondChars,100, 50,6,YELLOW); |
332 | }
|
333 | |
334 | }
|
335 | |
336 | LastHour = clock.hour; |
337 | LastMinute = clock.minute; |
338 | LastSecond = clock.second; |
339 | |
340 | }
|
341 | |
342 | }
|
343 | void doEncoder() { |
344 | |
345 | |
346 | if (digitalRead(2) == digitalRead(3)) { |
347 | if (Volume > 0) { |
348 | Volume--; |
349 | VolumeUpDown = -1; |
350 | VolumeChangeWished=1; |
351 | }
|
352 | } else { |
353 | if (Volume < 15) { |
354 | Volume++; |
355 | VolumeUpDown = 1; |
356 | VolumeChangeWished=1; |
357 | }
|
358 | |
359 | }
|
360 | |
361 | }
|
Das ist der Code mit dem ich aktuell Teste. Ist aber noch nix gescheites. Damit hatte ich noch rumprobiert bevor ich die Platinen gemacht hatte und alles noch ein Testaufbau war. Er springt öfters mal in diese Verzweigung rein
1 | if (SeekWished==1) .. |
obwohl SeekWished niemals auf 1 gesetzt wurde. Das mit dem Fm Tuner habe ich mir fast schon gedacht. Werde gleich mal nen dicken Elko anlöten. Ansonsten gibt es nochmals eine Platine mit einem EMI-Shield um den Tuner. Das einzigste was mir jetzt noch rießen Rätsel bereitet ist, warum das XS3868 nicht richtig starten will, wenn die Platinen verbunden sind. Habe Testweise nur mal die I2C Leitungen + Masse an die Audioplatine geführt, also ohne UART + 5V und selbst dann startet er nicht richtig. Sind beide Platinen komplett getrennt startet der XS3868 immer korrekt. Eine gemeinsame Masse dagegen macht ihm nichts aus. Die I2C Leitungen haben doch aber 0 mit dem XS3868 etwas zu tun in der Schaltung.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.