Forum: Mikrocontroller und Digitale Elektronik MC reagiert nur auf das erste Bluetooth-Paket


von Lukas S. (mogfox)


Lesenswert?

Hallo,

Ich arbeite gerade an einer Steckdosenleiste, die per Bluetooth 
steuerbar sein soll. Dazu verwende ich 3 Steckdosen, die mit Relais über 
einen Atmega328P gesteuert werden und für die Bluetoothverbindung ein 
HC-05 Bluetooth-Modul.
Mit Bluetooth Serial Terminal verschicke/empfange ich daten zum/vom MC.

Mein problem:
Das Verschicken von daten vom MC ist kein problem,genauso wie das erste 
Paket, das ich vom PC schicke. Dieses kommt an und tut das was es soll, 
aber die darauf folgenden lösen gar keine Reaktion aus. Nur wenn ich 
nichts schicke(also nur Carriage Return)kommt eine 0 an und wird 
erkannt. Schicke ich eine 0 löst diese aber auch keine reaktion aus.

Hier mein code:
1
'----------------------------------
2
'|Lukas Sauer 2016                |
3
'|Bluetooth-Steckdosenverteiler   |
4
'----------------------------------
5
$regfile = "m328Pdef.dat"
6
$crystal = 1000000
7
$baud = 9600
8
9
Dim Empfangen As Byte
10
11
Config Portb.0 = Output                                     'Piezo
12
Config Portc.5 = Output                                     'Dose1
13
Config Portc.4 = Output                                     'Dose2
14
Config Portc.3 = Output                                     'Dose3
15
Config Portc.2 = Output                                     'LED1
16
Config Portc.1 = Output                                     'LED2
17
Config Portc.0 = Output                                     'LED3
18
19
Dose1 Alias Portc.5
20
Dose2 Alias Portc.4
21
Dose3 Alias Portc.3
22
Led1 Alias Portc.2
23
Led2 Alias Portc.1
24
Led3 Alias Portc.0
25
Piezo Alias Portb.0
26
27
Dose1 = 0
28
Dose2 = 0
29
Dose3 = 0
30
Piezo = 0
31
32
Sound Piezo , 250 , 400
33
34
Print "ready"
35
Echo Off
36
37
Do
38
   Input Empfangen
39
   Print "Empfangen:"
40
   Print Empfangen                                          'Bluetooth empfangen
41
42
   Select Case Empfangen
43
      Case 1 :
44
         Dose1 = 0
45
         Led1 = 0
46
         Sound Piezo , 250 , 350
47
         Print "Case 1"
48
      Case 2 :
49
         Dose1 = 1
50
         Led1 = 1
51
         Sound Piezo , 250 , 500
52
         Print "Case 2"
53
      Case 3 :
54
         Dose2 = 0
55
         Led2 = 0
56
         Sound Piezo , 250 , 350
57
         Print "Case 3"
58
      Case 4 :
59
         Dose2 = 1
60
         Led2 = 1
61
         Sound Piezo , 250 , 500
62
         Print "Case 4"
63
      Case 5 :
64
         Dose3 = 0
65
         Led3 = 0
66
         Sound Piezo , 250 , 350
67
         Print "Case 5"
68
      Case 6 :
69
         Dose3 = 1
70
         Led3 = 1
71
         Sound Piezo , 250 , 500
72
         Print "Case 6"
73
      Case Else :
74
         Sound Piezo , 250 , 600
75
         Sound Piezo , 250 , 400
76
         Print "Case else"
77
   End Select
78
Loop
79
End

->  Bitte Rechtschreibung und kleine Fehler nicht so ernst nehmen.ICH 
BIN ERST 13 JAHRE ALT!!

Mfg Lukas S.

von void (Gast)


Lesenswert?

Hallo Lukas,

  > Nur wenn ich nichts schicke(also nur Carriage Return)kommt eine 0 an
  > Schicke ich eine 0 löst diese aber auch keine reaktion aus.

nach deinem Programm ist eine besondere Funktion nur für Werte von 1-6 
definiert. Für alle anderen Werte, so auch 0, wird die Funktion vom 
"Case Else" bestimmt.

Auch solltest du klar unterscheiden zwischen einem Wert 0 (Null 
character) und dem Wert des ASCII Zeichens "0" (mit Wert 48). siehe 
http://www.ascii-code.com/
Das Zeichen bei dem du annimmst das der Wert Carrige Return (13) 
gesendet wird ist wohl in Wirklichkeit der Null character (0).

Leider bin ich etwas aus der Übung mit Basic. Aber ich versuche es 
trotzdem mal zu deuten.
1
Dim Empfangen As Byte
2
...
3
Input Empfangen
4
...
5
Select Case Empfangen
6
  Case 1 :

Du empfängst jeweils ein Byte und arbeitest dieses eine Byte ab.
Falls dein Sender eine "1" schicken soll, sendet dieser zwei Bytes auf 
einmal; Erst eine "1" (Wert 49) und dann ein Null char (Wert 0). Diese 
werden aber nach einander verarbeitet. Du empfängst also einmal den Wert 
49 und einmal den Wert 0.
Letzteres hast du wohl auch beobachtet.

Sinnvoll ist wohl deine Zeichenkette (String) als ganzes zu Empfangen 
und zu verarbeiten. Das sollte vermutlich so in Basic geschrieben 
werden:
1
Dim Empfangen As String
2
...
3
Input Empfangen
4
...
5
Select Case Empfangen
6
  Case "1" :

Dein Vorhaben (Relais/LED Steuerung über Bluetooth) und deine 
Rechtschreibung ;-) sind beide vollkommen okay für dein Alter. Nur bevor 
du die 230V-Seite hinter den Relais wirklich an die Steckdose 
anschließt, lasse bitte nochmal einen Erwachsenen mit Erfahrung über 
deinen Aufbau schauen. Die Gefahr ist sonst zu groß.

von Lukas S. (mogfox)


Lesenswert?

Danke für die schnelle Antwort!

Nur leider hat das nicht so ganz geklappt. Obwohl ich jetzt "Empfangen" 
zu einem String(=Zeichenkette) gemacht habe und die Cases dem jeweiligen 
ASCII-Codes angepasst habe. Trotzdem sprigt der Code immernoch in den 
"Case else".
Ich habe das senden auch schon mit anderen Terminals ausprobiert, also 
an dem liegt es mal auch nicht. :-)

MFG Lukas S.

von Harry U. (harryup)


Lesenswert?

Hi Lukas,
wie void schon geschrieben hat, empfängst du im Regelfall mehr als nur 1 
Zeichen, 'normalerweise' hängt an dem gesendeten Zeichen noch ein CR/LF, 
was zwar letztlich in der case else verarbeitet wird, aber du brauchst 
zunächst mal eine Kontrolle, was hier wirklich empfangen wird.
Bewährt hat sich in meinen Lösungen ein Empfangspuffer, der auf das 
letzte Zeichen eines Empfangs reagiert und einen ISR auslöst, sinnvoll 
vor allem dann, wenn in der mainloop noch anderer Code abgearbeitet 
werden soll.
Versuch mal:

' Empfangspuffer für 12 Bytes inkl. CR/LF, ISR bei LF aus CR/LF
' als Bytematch kann auch jedes andere Zeichen definiert werden
Config Serialin = Buffered , Size = 12 , Bytematch = 10

dim Bytes as Bytes
dim EP1 as string * 1
dim EP12 as string * 12
enable interrupts

do
...
loop
end

' ISR löst aus, wenn CHR(10) oder CHR(Bytematch) empfangen wurde
Serial0charmatch:
   Bytes = 0                    ' Zähler nullen
   EP12 = ""                    ' String leeren
   While Ischarwaiting() = 1    ' min. 1 Byte im Puffer...
      Ep1 = Inkey()             ' auslesen und...
      Incr Bytes                ' Zähler erhöhen
      Ep12 = Ep12 + Ep1         ' ...zu String hinzufügen
   Wend
   Clear Serialin0              ' Puffer leeren
   Print Bytes                  ' Bytes an Master
   Print Ep12                   ' String inkl. CR/LF an Master
Return

UFFBASS: die Nummer, die gesendet wurde, liegt zunächst immer als String 
vor, spiele mal ein wenig mit der val() Funktion oder frage in der 
select ab: case "1": ... case "6":

Grüssens, harry

von Lukas S. (mogfox)


Angehängte Dateien:

Lesenswert?

Vielen Dank,

jetzt hat es geklappt! Alles läuft so wie es soll.


Da hätte ich noch  eine Frage zur Hardware. Welche Transistoren kann ich 
verwenden um die 5V-Relais zu schalten?Meine Spannungsquelle ist ein 
altes Nitendoladegerät mit 5.2V DC Output. Mit diesem Strom sollen die 
relais geschalten werden. Könnte es vieleicht ein Problem sein, dass 
alle Relais dicht nebeneinander sind(ich meine wegen dem Mangetfeld 
könnten sie sich gegenseitig beeinflussen)(siehe Foto)?

Mfg Lukas

von void (Gast)


Lesenswert?

Harry U. schrieb:
> [...] du brauchst zunächst mal eine Kontrolle, was hier
> wirklich empfangen wird.
> Bewährt hat sich in meinen Lösungen ein Empfangspuffer, [...]

Wahre Worte, welche sich Lukas offensichtlich geholfen haben. ;-)

Lukas S. schrieb:
> jetzt hat es geklappt! Alles läuft so wie es soll.
>
> Da hätte ich noch  eine Frage zur Hardware. Welche Transistoren kann ich
> verwenden um die 5V-Relais zu schalten?

Das kommt auf den Strom an, welcher deine Relais auf der Eingangs-Seite 
zum schalten benötigen. Falls 100mA (bei 5V) schon ausreichen passt als 
NPN-Transistor z.B. ein BC846(SMD) oder BC847. Siehe auch
https://www.mikrocontroller.net/articles/Relais_mit_Logik_ansteuern

> Könnte es vielleicht ein Problem sein, dass
> alle Relais dicht nebeneinander sind(ich meine wegen dem Magnetfeld
> könnten sie sich gegenseitig beeinflussen)(siehe Foto)?

Nein. Das Magnetfeld außerhalb der Spule (=durch die Luft) ist zu 
gering. Typischerweise kannst du solche Relais ohne Probleme direkt 
nebeneinander verbauen.

Ich möchte aber kurz drauf hinweisen, dass es so aussieht als wenn bei 
deinem Aufbau die Mindest-Isolations-Abstände zwischen 230V-Netz-Seite 
und 5V-Seite nicht ausreichen. Bitte betreibe das so nicht mit 
Netzspannung.

von Lukas S. (mogfox)


Lesenswert?

Danke für den Hinweis,

daran hätte ich jetzt wirklich nicht gedacht!Ist es ausreichent wenn ich 
alles noch einmal gut isoliere oder sollte ich die Schaltung neu machen? 
:-)

void schrieb:
> Falls 100mA (bei 5V) schon ausreichen passt als
> NPN-Transistor z.B. ein BC846(SMD) oder BC847.

Ja die passen gut, weil die Relais nur 0.8 mA ziehen.Ich werde sie 
morgen gleich besorgen.

Mfg Lukas

von void (Gast)


Lesenswert?

Lukas S. schrieb:
> Ist es ausreichend wenn ich alles noch einmal gut isoliere
> oder sollte ich die Schaltung neu machen?

Ich fürchte das wird schwer mit dem "noch einmal gut isolieren".
Auf deinem Foto erkennt man z.B. unten an den Relais deutlich <1mm 
Abstand zwischen ab-isolierter/verzinnter GND-Leitung (Relais 
Primär-Seite - schwarzes Kabel) und 230V-Zuleitung (Relais 
Sekundär-Seite - braunes Kabel). Dieser Isolations-Abstand sollte aber 
>=4mm betragen. Je nach Verschmutzungs-Grad der Umgebung auch mehr.

Außerdem sind deine Relais für Print-Montage, also zum auflöten auf 
Platinen. Direkt angelötete Kabel am Relais gehen gar nicht, weil durch 
die mech. Belastung die Beinchen vom Relais abfallen werden...

Und an die Kabeldurchführungen (durch das Gehäuse) gehören 
Zugentlastungen. Damit wenn jemand/etwas draußen am Kabel zieht diese 
nicht gleich von der Platine abspringen.


Unterm Strich musst du das also aus mehreren Gründen neu machen.
Ich verstehe, dass du es bisher nicht besser wusstest und es deshalb so 
gebaut hast wie es jetzt eben ist. Aber so gehört das nicht ans Netz 
angeschlossen.

Ich möchte dir nicht den Spaß am basteln vermiesen, deshalb folgende 
alternative Möglichkeiten:
1) Du baust das ordentlich nochmal auf einer Leiterplatte auf und lässt 
das von einem Elektriker aus dem Verwandtenkreis abnehmen.
2) Du benutzt gekaufte Relais-Module. Die gibt es mit 2, 4 oder 8 Relais 
und Transistoren gleich drauf. Wenn du hier im Forum mal suchst findest 
du auch bestimmt schnell passende Empfehlungen für solche Relais Module.
3) Du baust 433MHz Funk-Steckdosen aus dem Baumarkt um. Solche 3er Sets 
mit einer Fernbedienung. Die Funk-Steckdosen bleiben unverändert. Die 
Fernbedienung wird umgebaut und an den uC angeschlossen. Gibt es auch 
passende Umbauanleitungen im Netz.

von Lukas S. (mogfox)


Lesenswert?

Oh schade,

jetzt werde ich wohl alles neu machen müssen. Trotzdem danke für die 
Hilfe.

MFG Lukas ;-)

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
Noch kein Account? Hier anmelden.