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 | }
|