Pluggit_Drucksensorboard_V3.ino


1
// Ersatzboard Drucksensor für Pluggit V3
2
// https://www.mikrocontroller.net/topic/477458
3
// Eingesetzer Controller: ArduinoProMini 3.3V/8MHz
4
// Sensoren: 2 Stück Sensirion SDP-810-500Pa
5
6
// Erstellt: 30.06.20  Daniel F.
7
8
// neu V2: Testfunktion um beide Ausgänge auf 10V zu schalten
9
// neu V2: Dämpfung des Sensorsignals
10
// neu V3: PWM nun auf Pins 9&10 mit 12bit Auflösung
11
// neu V3: Nachbildung auch von der neueren SDP1000-L05-Platine wenn Pin2 auf GND gesetzt ist
12
13
14
const int PWM10VS1 = 3930;   //PWM(0...4095) für Justage 10V-Ausgangsspannung Sensor1 (Abgleich Analogschaltung Spannungsverstärker)
15
const int PWM10VS2 = 3930;   //PWM(0...4095) für Justage 10V-Ausgangsspannung Sensor2 (Abgleich Analogschaltung Spannungsverstärker)
16
17
#include <Wire.h>
18
19
float Sensor1=0.0;
20
float Sensor2=0.0;
21
int PWM1=0;
22
int PWM2=0;
23
boolean SDP1000L05;
24
25
26
void setup() {
27
  setupPWM12();
28
  pinMode(2, INPUT_PULLUP);
29
  pinMode(3, INPUT_PULLUP);
30
  Wire.begin();
31
  Serial.begin(9600);  
32
  if (!digitalRead(3)) AOTest();        //wenn nach Reset Pin3 auf GND gebrückt Analogausgänge zum Test für 15s auf 10V 
33
  SDP1000L05 = !digitalRead(2);         //wenn Pin2 auf GND dann eine SDP1000L05-Platine nachbilden 
34
  if (SDP1000L05) Serial.println("Sensornachbildung: SDP1000L05"); else  Serial.println("Sensornachbildung: SMI5552-003-D");
35
}
36
37
38
void loop() {
39
40
  multiplexer(0);                       // Schalte I2C-Multiplexer PCA9540B auf Kanal0 (Sensor1)
41
  
42
  Sensor1=(Sensor1+SDP810lesen())/2.0;  // Drucksensor1 lesen und Dämpfung
43
  
44
  multiplexer(1);                       // Schalte I2C-Multiplexer PCA9540B auf Kanal1 (Sensor2)
45
  
46
  Sensor2=(Sensor2+SDP810lesen())/2.0;  // Drucksensor2 lesen und Dämpfung
47
48
  Serial.print("S1: ");                 // serielle Ausgabe zur Diagnose
49
  Serial.print(Sensor1,1);
50
  Serial.print("Pa  S2: ");
51
  Serial.print(Sensor2,1);
52
  Serial.println("Pa");
53
54
55
  if (SDP1000L05) {                                                 //Nachbildung der neuen Platine mit SDP1000L05-Sensoren
56
    PWM1 = mapf(Sensor1, -6.43, 146.3, PWM10VS1*0.0825, PWM10VS1/2.0);  //Druckbereich auf Ausgangssignal anpassen
57
    PWM2 = mapf(Sensor2, -6.43, 146.3, PWM10VS1*0.0825, PWM10VS2/2.0);  //-6.4Pa=0.825V bis 146.3Pa=5.00V
58
59
    PWM1 = constrain(PWM1, 0, PWM10VS1/2);                          //Wertebereich PWM begrenzen, max 5.0V
60
    PWM2 = constrain(PWM2, 0, PWM10VS2/2); 
61
  }
62
  else{                                                             //Nachbildung der alten Platine mit SMI5552-003-D-Sensoren
63
    PWM1 = mapf(Sensor1, -70.0, 284.0, 0.0, PWM10VS1);              //Druckbereich auf Ausgangssignal anpassen
64
    PWM2 = mapf(Sensor2, -70.0, 284.0, 0.0, PWM10VS2);              //-70Pa=0.0V bis 284Pa=10.0V
65
    
66
    PWM1 = constrain(PWM1, 0, PWM10VS1);                            //Wertebereich PWM begrenzen, max 10.0V
67
    PWM2 = constrain(PWM2, 0, PWM10VS2); 
68
  }
69
70
  analogWrite12(9, PWM1);
71
  analogWrite12(10, PWM2);
72
73
}
74
75
76
void multiplexer(bool kanal){
77
  Wire.beginTransmission(0x70); // I2C-Multiplexer PCA9540B
78
  Wire.write(0x04+kanal);       // Kanal 0 oder 1
79
  Wire.endTransmission(); 
80
}
81
82
83
float SDP810lesen(){
84
  
85
  int Druck=0;
86
  
87
  // Lesebefehl an Drucksensor (SDP810) senden
88
  Wire.beginTransmission(0x25);   // transmit to device
89
  Wire.write(0x36);               // Measurement triggering
90
  Wire.write(0x2F);               // Measurement triggering
91
  Wire.endTransmission();         // stop transmitting
92
93
  delay(50);                      // Messzeit=45ms
94
95
  // 2 Bytes anfordern
96
  Wire.requestFrom(0x25, 2);      // request 2 bytes from slave device
97
98
  // und lesen
99
  if (2 <= Wire.available()) {
100
    Druck = Wire.read();          // high byte lesen
101
    Druck = Druck << 8;           // nach links schieben
102
    Druck |= Wire.read();         // low byte lesen OR high byte
103
  }
104
  return Druck/58.0;              // anpassen auf Pa (Teiler ist Normal 60, nach Korrektur mit ca 1m 4mm-Schlauch neuer Teiler 58)
105
}
106
107
108
int mapf(float x, float in_min, float in_max, float out_min, float out_max)
109
{
110
    return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
111
}
112
113
114
void AOTest(){
115
  analogWrite12(9, PWM10VS1);
116
  analogWrite12(10, PWM10VS2);
117
  delay(15000);
118
}
119
120
121
void setupPWM12() {
122
    DDRB |= _BV(PB1) | _BV(PB2);        /* set pins as outputs */
123
    TCCR1A = _BV(COM1A1) | _BV(COM1B1)  /* non-inverting PWM */
124
        | _BV(WGM11);                   /* mode 14: fast PWM, TOP=ICR1 */
125
    TCCR1B = _BV(WGM13) | _BV(WGM12)
126
        | _BV(CS11);                    /* prescaler 1 */
127
    ICR1 = 0x0fff;                      /* TOP counter value (freeing OCR1A*/
128
}
129
/* Comments about the setup
130
Changing ICR1 will effect the amount of bits of resolution.
131
ICR1 = 0xffff; (65535) 16-bit resolution
132
ICR1 = 0x3FFF; (16383) 14-bit resolution 
133
ICR1 = 0x0FFF; (4095) 12-bit resolution etc....
134
135
Changing the prescaler will effect the frequency of the PWM signal.
136
Frequency[Hz}=CPU/(ICR1+1) where in this case CPU=16 MHz
137
16-bit PWM will be>>> 16000000/(65535+1)=244,14Hz
138
*/
139
140
141
142
void analogWrite12(uint8_t pin, uint16_t val)
143
/* 12-bit version of analogWrite(). Works only on pins 9 and 10. */
144
{
145
    switch (pin) {
146
        case  9: OCR1A = val; break;
147
        case 10: OCR1B = val; break;
148
    }
149
}