Forum: Mikrocontroller und Digitale Elektronik Arduino: Keine Übersprechdämpfung?


von Alexander S. (knut740)


Lesenswert?

Hallo
ich habe auf einem Arduino-Leonardo zwei nebeneinanderliegende 
Digitalports für die Abfrage zweier SMT160-30 eingerichtet, von denen 
das (noch unfertige)Programm auch richtige Ergebnisse liefert.

A B E R : derzeit habe ich mit zunächst nur einem Sensor operiert und 
dabei mußte ich feststellen, daß immer ein richtiges Ergebnis angezeigt 
wird, egal, an welchen der beiden Ports ich den Sensor angsteckt habe.

Also: sensorpin1 abgefragt und Sensor an den Port für sensorpin1 
angeschlossen - ok. Aber sensorpin1 abgefragt und Sensor an den Port für 
sensorpin2 angeschlossen? Wert ist auch ok.
Nur wenn ich den Port auf OUTPUT schalte, kriege ich Ruhe.
Kann mir vielleicht jemand auf die Sprünge helfen?
Ein Schnipsel des Programms füge ich bei. Es geht um Pin 11 und 12 und 
dann weiter unten um pulseIn, leider kriege ich keine Zeilennummern in 
das beigefügte Programm
1
#include <EEPROM.h>
2
#include <Wire.h> 
3
#include <LiquidCrystal_I2C.h>
4
#define sensorpin1 11                   // Anschluß des ersten SMT160-30-1
5
#define sensorpin2 12                   // Anschluß des zweiten SMT160-30
6
#define LEDpin 13
7
8
LiquidCrystal_I2C lcd(0x20,16,2);      
9
int eepromaddress = 0;                 // <---------   
10
byte eepromwert; 
11
int cyclen = 5000;                     // wie oft wird ein Sensor      //abgefragt, bis daraus ein Mittelwert gebildet wird
12
float high, low;                       // float -3.4 E38 bis +3.8 E38 (4 Byte)
13
float High, Low;
14
float Temp;
15
int i;                                 // +/- 32768 (2byte)
16
float a;                               // wird für die Ziffernausgabe benötigt
17
int eepromintervall = 20;               // nach wieviel LCD-Ausgaben wird  //ein Wert ins EEPROM geschrieben  <--
18
byte highbyte, lowbyte;
19
 
20
....snip...
21
22
void loop()
23
   {              
24
//............ Start Eepromintervall            
25
    for (int n=0; n < eepromintervall; n++) // n .... wie oft werden   Daten auf LCD angezeigt,
26
    {                                           // bis einer ins EEPROM //geschrieben wird
27
       unsigned long highcounts = 0;
28
       unsigned long highcountsum = 0;
29
       unsigned long lowcounts = 0;
30
       unsigned long lowcountsum = 0;
31
       for (int i=0; i<cyclen; i++)                     // Erfassung der //highcounts des SMT-Sensors
32
       { 
33
         highcounts = pulseIn(sensorpin1, HIGH, 500);    // die Zahl 500 //bedeutet timeout nach 500 ms
34
         highcountsum = highcountsum + highcounts;
35
       }
36
37
       for ( i=0; i < cyclen; i++)                      // Erfassung der lowcounts des SMT-Sensors
38
       {
39
         lowcounts = pulseIn(sensorpin1, LOW, 500);
40
         lowcountsum = lowcountsum + lowcounts;
41
...snip...

: Bearbeitet durch User
von Jan H. (jan_h565)


Lesenswert?

Diese sensor ist ein digital sensor, wo das den duty cycle die 
temperatur gibt. Bei ein offen Eingang ist die Ergebnis beim lesen nicht 
definiert : es kan high oder low sein. Das bedeutet das du sowieso 
irgend eine "Mittelwert duty cycle" lest, auch ohne Sensor ! Wen diesen 
Sensor keine Pullup / Pulldown akzeptiert, kanst du auch die Periode von 
jeden Puls checken, das soll die Speification entsprechen.

von Peter D. (peda)


Lesenswert?

CMOS-Eingänge sind hochohmig. Da können sich kapazitiv Signale 
einkoppeln, wenn die Leitungen parallel liegen.

von Alexander S. (knut740)


Lesenswert?

Stimmt!
Ich habe am leeren Eingang einen Pulldownwiderstand angebracht und nun 
funktioniert es so, wie man sich das denkt.

Vielen Dank für Eure freundliche Hilfe!
VG

von Alexander S. (knut740)


Angehängte Dateien:

Lesenswert?

Das Problem ist leider keinesfalls gelöst, vielmehr wird es mysteriöser.

Ich habe zwei SMT160-30 an nebeneinader liegende Pins (11 u. 12) 
angeschlossen. Wenn man nichts tut, erhält man eine gerade Linie der 
Temperatur über die Zeit, wie es sich gehört.
Dann habe ich einen der Sensoren mit den Fingern erwärmt und dann 
erstaunt festgestellt, daß auch der andere eine höhere Temperatur zeigte 
(nein, es ist nicht die Strahlungswärme der Hand, das habe ich zuerst 
getestet, dazu sind sie zu weit voneinander entfernt.)

Dann habe ich mich an Eure Beiträge von hochohmigen Eingängen erinnert 
(was allerding nun nicht mehr zutrifft, weil die Eingänge jetzt belegt 
sind).
Trotzdem: die Sensoren habe ich jetzt an Pin 8 und 12 angeschlossen.

Es gibt aber keinen Unterschied zwischen nahen und entfernten 
Anschlüssen, wie die beiden beigefügten Diagramme zeigen.
Die blaue Linie ist die Temperaturkurve des einen Sensors, den ich mit 
den Fingern berührt habe, die rote Linie liefert der daneben hängeende 
Sensor.

Gibt es eine Erklärung?

VG
Alexander

von Achim (Gast)


Lesenswert?

Dann poste die Auswertung im Code.

von Jan H. (jan_h565)


Lesenswert?

Post mal die complette Code, moglich ist da noch etwas falsch.

von Alexander S. (knut740)


Lesenswert?

Jan H. schrieb:
> Post mal die complette Code, moglich ist da noch etwas falsch.

Mache ich. Ist aber problematisch, da ich derzeit nur eine unaufgeräumte 
Arbeitsversion habe. Wenn ich aber jetzt make up betreibe, würde ich 
vielleiicht für Euch aufschlußreiche Stellen beseitigen.

Ich schicke Euch also die Version, so wie sie ist:

1
// __Start_4_SMT_I2C_LCD_EEPROM                                29.11.16
2
// __Start_3_SMT_I2C_LCD_EEPROM                                29.11.16
3
4
//                                                              21. Jan 2013
5
// zugehörige Ergebnis-Abfrage:  _int_EEPROM_auslesen_1_Wert    21.11.2015
6
//                     bzw.      _EEPROM-2-Werte
7
8
// - Zwei  SMT160-30 werden abgefragt,
9
// - auf dem I2C-LCD dargestellt (auch negative Zahlen)
10
// - als int in jeweils zwei Bytes zerlegt und in aufeinanderfolgen EEPROM-Zellen gespeichert;
11
12
// Hardware: 
13
// Leonardo auf 1151113
14
// I2C-LCD
15
16
// Als IDE wahrscheinlich nur Version 0022 brauchbar
17
//(die verwendeten I2C/LCD Dateien sind evtll nicht angepaßt).
18
19
// verbesserungsbedürftig!
20
// derzeit einfach nur die Pin1-Abfrage komplett(!!!) kopiert als Pin2-Abfrage
21
// Codereste für die Verfolgung von Variablen entfernen
22
// Probleme: Beeinflussung von PIN2 durch PIN1
23
24
25
26
#include <EEPROM.h>
27
#include <Wire.h> 
28
#include <LiquidCrystal_I2C.h>
29
30
int eepromaddress = 0;                 // <---------   XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
31
byte eepromwert;
32
33
LiquidCrystal_I2C lcd(0x20,16,2);      // Achtung: auf den neuen I2C-LCD gibt es Adressjumper.
34
                                       // Alle gesetzt, gibt I2C-Adresse 0x27  (ox20?),
35
                                        
36
#define LEDpin 13
37
int sensorpin1 = 8;                   // Vorlauf   Anschluß des SMT160-30
38
int sensorpin2 = 12;                   // außen
39
40
int cyclen = 2500;                     // wie oft wird ein Sensor abgefragt, bis daraus ein Mittelwert gebildet wird
41
float high, low;                       // float -3.4 E38 bis +3.8 E38 (4 Byte)
42
float High, Low;
43
float Temp, Temp1 ,Temp2;
44
int i;                                 // +/- 32768 (2byte)
45
float a;                               // wird für die Ziffernausgabe benötigt
46
int eepromintervall = 20;             // nach wieviel LCD-Ausgaben wird ein Wert ins EEPROM geschrieben  <-------  XXXXXXXXXXXXXXXXX
47
byte highbyte, lowbyte;
48
 
49
 void setup() 
50
    {
51
    pinMode (13, OUTPUT);              // z. Zt. unbenutzt
52
    pinMode (8, INPUT);                // sensorpin1 als Eingang setzen
53
    pinMode (12, INPUT);               // sensorpin2 als Eingang setzen
54
    
55
    Serial.begin(9600);                // für Ausgabe über Terminal
56
  
57
    lcd.init();
58
    lcd.backlight();
59
    lcd.clear();
60
    lcd.print("4 SMT + I2C-LCD");
61
    lcd.setCursor(0,1);
62
    lcd.print("EEPRONM high+lowbyte");
63
    delay(4000);
64
    lcd.clear();
65
  }
66
67
void loop()
68
   {              
69
//....................................... Start Eepromintervall xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx              
70
    for (int n=0; n < eepromintervall; n++)     // wie oft werden Daten auf LCD angezeigt,
71
    {                                           // bis einer ins EEPROM geschrieben wird
72
73
       unsigned long highcounts = 0;
74
       unsigned long highcountsum = 0;
75
       unsigned long lowcounts = 0;
76
       unsigned long lowcountsum = 0;
77
78
//   ----Anfang---von-----P I N 1 ---------------------------------------------------------------------
79
 
80
       for (int i=0; i<cyclen; i++)                     // Erfassung der highcounts des SMT-Sensors
81
       { 
82
         highcounts = pulseIn(sensorpin1, HIGH, 500);    // die Zahl 500 bedeutet timeout nach 500 ms
83
         highcountsum = highcountsum + highcounts;
84
       }
85
86
       for ( i=0; i < cyclen; i++)                      // Erfassung der lowcounts des SMT-Sensors
87
       {
88
         lowcounts = pulseIn(sensorpin1, LOW, 500);
89
         lowcountsum = lowcountsum + lowcounts;
90
       }
91
                                                 // Zahlenbereiche: counts z.B. 300, cyclen*counts=600.000, *200 -> 120.000.000
92
    
93
       highcounts = highcountsum / cyclen;
94
       High = float (highcounts);                      // Umwandlung der Counts in float, zweckmäßig für die  
95
       lowcounts = lowcountsum / cyclen ;              // Ermittlung der Temperatur mit der u.g. Formel
96
       Low  = float (lowcounts);       
97
      
98
99
   
100
      lcd.clear();                                    // Darstellung der Rohwerte auf dem I2C-LCD
101
      delay(100);
102
      lcd.setCursor(0,1);
103
      lcd.print("HLS");                               // HLS = High / Low / Summe
104
      lcd.print(" ");  
105
      lcd.print(int(highcounts));                                        
106
      lcd.print(" "); 
107
      lcd.print(int(lowcounts));                       
108
      lcd.print(" ");   
109
      lcd.print(int(lowcounts + highcounts));    
110
111
   
112
     Temp = tempberechnung(High,Low);                // Berechnung der Temperatur mit   Temp = float       
113
     lcd.setCursor(0,0);
114
     lcd.print("aussen-1");     
115
     lcd.setCursor(11,0);                            // Umwandlung in int erst in den Unterprogrammen
116
117
     Ausgabe(Temp);
118
     delay(2000);
119
 
120
//     lcd.clear();
121
//     lcd.print(int(eepromaddress));
122
//     delay(1000);
123
     Serial.print(Temp);                         // Gibt  Temp über das Terminal aus (mit unangemessener Stellenzahl)
124
     Serial.println();
125
     Temp1 = Temp;
126
//   ----Ende---von-----P I N 1 --------------------------------------------------------------------- 
127
128
//   ----Anfang---von---P I N 2 ---------------------------------------------------------------------
129
130
       for (int i=0; i<cyclen; i++)                     // Erfassung der highcounts des SMT-Sensors
131
       { 
132
         highcounts = pulseIn(sensorpin2, HIGH, 500);    // die Zahl 500 bedeutet timeout nach 500 ms
133
         highcountsum = highcountsum + highcounts;
134
       }
135
136
       for ( i=0; i < cyclen; i++)                      // Erfassung der lowcounts des SMT-Sensors
137
       {
138
         lowcounts = pulseIn(sensorpin2, LOW, 500);
139
         lowcountsum = lowcountsum + lowcounts;
140
       }
141
                                                 // Zahlenbereiche: counts z.B. 300, cyclen*counts=600.000, *200 -> 120.000.000
142
    
143
       highcounts = highcountsum / cyclen;
144
       High = float (highcounts);                      // Umwandlung der Counts in float, zweckmäßig für die  
145
       lowcounts = lowcountsum / cyclen ;              // Ermittlung der Temperatur mit der u.g. Formel
146
       Low  = float (lowcounts);       
147
      
148
149
   
150
      lcd.clear();                                    // Darstellung der Rohwerte auf dem I2C-LCD
151
      delay(100);
152
      lcd.setCursor(0,1);
153
      lcd.print("HLS");                               // HLS = High / Low / Summe
154
      lcd.print(" ");  
155
      lcd.print(int(highcounts));                                        
156
      lcd.print(" "); 
157
      lcd.print(int(lowcounts));                       
158
      lcd.print(" ");   
159
      lcd.print(int(lowcounts + highcounts));    
160
161
   
162
      Temp = tempberechnung(High,Low);                // Berechnung der Temperatur mit   Temp = float       
163
     lcd.setCursor(0,0);
164
      lcd.print("Vorlauf-2");     
165
     lcd.setCursor(11,0);                              // Umwandlung in int erst in den Unterprogrammen
166
     Ausgabe(Temp);                    
167
     delay(2000);
168
     Temp2 = Temp;
169
//   ----Ende---von-----P I N 2 ---------------------------------------------------------------------   
170
171
172
     lcd.clear();
173
     lcd.setCursor(0,0);
174
     lcd.print(Temp1/100);                            // Gibt  Temp über das Terminal aus (mit unangemessener Stellenzahl)
175
     lcd.setCursor(0,1);
176
     lcd.print(Temp2/100);
177
     lcd.setCursor(12,1);        
178
     lcd.print(int(eepromaddress));
179
     delay(6000);
180
/* 
181
     lcd.clear();
182
     lcd.print(int(eepromaddress));
183
     delay(1000);
184
     lcd.print(Temp1);     // Gibt  Temp über das Terminal aus (mit unangemessener Stellenzahl)
185
186
     lcd.println();
187
     delay(4000);
188
*/
189
   
190
   } //................................Ende Eepromintervall xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
191
192
//       lcd.clear();
193
//       Ausgabe(Temp);                                // ist Temp hier angekommen? Müßte noch float sein
194
//       Temp = -1234.0;
195
       int Tempa = int(Temp1);                        // float in int verwandeln, zwecks korrekter Zerlegung in zwei Byte,
196
       highbyte = highByte(Tempa);                   // weil nur Bytes EEPROM-gerecht sind
197
       lowbyte = lowByte(Tempa);
198
       EEPROM.write(eepromaddress, highbyte);  
199
       eepromaddress++;
200
       EEPROM.write(eepromaddress, lowbyte);  
201
       eepromaddress++; 
202
       
203
              int Tempb = int(Temp2);                        // float in int verwandeln, zwecks korrekter Zerlegung in zwei Byte,
204
       highbyte = highByte(Tempb);                   // weil nur Bytes EEPROM-gerecht sind
205
       lowbyte = lowByte(Tempb);
206
       EEPROM.write(eepromaddress, highbyte);  
207
       eepromaddress++;
208
       EEPROM.write(eepromaddress, lowbyte);  
209
       eepromaddress++; 
210
       
211
212
  
213
  }                       // Ende von loop XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
214
 
215
// Unterprogramme (in C  o b e n  angeordnet, bei Arduino:  u n t e n !) 
216
217
   float tempberechnung( float highcts, float lowcts)
218
    {     
219
      float temp;
220
      temp = (( highcts / (highcts + lowcts + 0.001)) - 0.320) / 0.0047;    // Summand 0.001 soll Division durch Null vermeiden
221
      temp = temp * 100;                    
222
      return(temp);
223
    }
224
 
225
/*
226
  void lcdtext(char* txt)
227
  {
228
    lcd.setCursor(1,0);
229
    lcd.print(txt);  
230
  }
231
*/ 
232
                                                      
233
  void Ausgabe(float a)                              // Zerlegung und Ausgabe einer vielstelligen Zahl, 
234
  {
235
    unsigned long ziff1, ziff2, ziff3, ziff4, ziff5, ziff6;  // long erf.??   
236
                                                     // umständliche Manipulation, weil keine Ausgaberoutine für größere Zahlwerte    
237
                                                     // in der mitgelieferten Headerdatei zu finden war.
238
     a = int(a);
239
//    a = -12345;
240
    if (a < 0)
241
    {                                                // für negative Temperaturwerte und weil es keine ordentliche Ausgabe als                   
242
      lcd.print("-");                                // int-Wert ist, sondern zehäckselt in einzelne Ziffern.
243
      a = a * (-1);
244
     }
245
     
246
    ziff1 = a / 1000;                                // Achtung, ziff1 ist nur dann die richtige Bezeichnung, wenn sie zum Divisor paßt;         
247
    lcd.print(ziff1);                                // wenn nicht, entsteht keine Ziffer, sondern eine mehrstellige Zahl!
248
    ziff2 = (a-ziff1*1000) / 100;                     // Wenn die Zahl zu klein ist, gibt es führende Nullen.
249
    lcd.print(ziff2); 
250
    lcd.print(",");
251
    ziff3 = (a-1000*ziff1 -ziff2*100) / 10;
252
    lcd.print(ziff3);
253
    ziff4 = (a-1000*ziff1 -ziff2*100 - ziff3*10) / 1;
254
    lcd.print(ziff4);
255
//       ziff5 = (a-10000*ziff1 - ziff2*1000 - ziff3*100 - ziff4*10)/1;
256
//       lcd.print(ziff5);
257
//       ziff6 = (a-ziff1*100000 - ziff2*10000 - ziff3*1000 - ziff4*100 -ziff5*10);  
258
//       lcd.print(ziff6);
259
    }
260
261
262
/*
263
 #include <stdlib.h>
264
  void drucke(int k)                           // itoa(umzuwandelnde int, Buffer, Zahlenbasis) (10=dezimal)
265
  {
266
   char Buffer[20];
267
   itoa( k, Buffer, 10 );
268
   lcd.print( Buffer );                        // ggf. auch lcd_out() o.ä. in anderen Libraries 
269
 }
270
*/

von Stefan (Gast)


Lesenswert?

Du hast ein Problem mit der Initialisierung deiner Variablen. Überlege 
mal, welchen Wert highcountsum und lowcountsum bei "Anfang---von---P I N 
2" haben.

von Alexander S. (knut740)


Lesenswert?

Ich glaube, ich weiß, woran es liegt:
Nach dem Kopieren der ganzen PIN1-Abfrage in PIN2 habe ich eine 
Fehlermeldung wegen doppelter Definition von Variablen bekommen. Darauf 
habe ich die vier Zeilen
1
       unsigned long highcounts = 0;
2
       unsigned long highcountsum = 0;
3
       unsigned long lowcounts = 0;
4
       unsigned long lowcountsum = 0;
einfach gelöscht, nicht daran denkend, daß die Variablen dann nicht mehr 
die benötigten Startwerte 0 enthalten.
Jetzt funktioniert es!

Vielen Dank für Eure Hilfe!

VG
Alexander

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.