-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathKnock_Shield_Example.ino
More file actions
153 lines (113 loc) · 5.19 KB
/
Knock_Shield_Example.ino
File metadata and controls
153 lines (113 loc) · 5.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
Example code compatible with the Knock Shield for Arduino.
Copyright (C) 2018 Bylund Automotive AB
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Contact information of author:
http://www.bylund-automotive.com/
info@bylund-automotive.com
Revision history:
2018-08-12 Rev. 1 First release to GitHub.
*/
//Define included headers.
#include <SPI.h>
//Define registers used.
#define SPU_SET_PRESCALAR_6MHz 0b01000100 /* 6MHz prescalar with SDO active */
#define SPU_SET_CHANNEL_1 0b11100000 /* Setting active channel to 1 */
#define SPU_SET_BAND_PASS_FREQUENCY 0b00101010 /* Setting band pass frequency to 7.27kHz */
#define SPU_SET_PROGRAMMABLE_GAIN 0b10100010 /* Setting programmable gain to 0.381 */
#define SPU_SET_INTEGRATOR_TIME 0b11001010 /* Setting programmable integrator time constant to 100µs */
#define MEASUREMENT_WINDOW_TIME 3000 /* Defining the time window of measurement to 3ms. */
//Define pin assignments.
#define SPU_NSS_PIN 10 /* Pin used for chip select in SPI communication. */
#define SPU_TEST_PIN 5 /* Pin used for chip select in SPI communication. */
#define SPU_HOLD_PIN 4 /* Pin used for chip select in SPI communication. */
#define LED_STATUS 7 /* Pin used for power the status LED, indicating we have power. */
#define LED_LIMIT 6 /* Pin used for the limit LED. */
#define UA_ANALOG_INPUT_PIN 0 /* Analog input for knock. */
//Function for transfering SPI data to the SPU.
byte COM_SPI(byte TX_data) {
//Set chip select pin low, chip not in use.
digitalWrite(SPU_NSS_PIN, LOW);
//Transmit and receive SPI data.
byte Response = SPI.transfer(TX_data);
//Set chip select pin high, chip in use.
digitalWrite(SPU_NSS_PIN, HIGH);
//Print SPI response.
Serial.print("SPU_SPI: 0x");
Serial.print(Response, HEX);
Serial.print("\n\r");
//Return SPI response.
return Response;
}
//Function to set up device for operation.
void setup() {
//Set up serial communication.
Serial.begin(9600);
//Set up SPI.
SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV16);
SPI.setBitOrder(MSBFIRST);
SPI.setDataMode(SPI_MODE1);
//Set up digital output pins.
pinMode(SPU_NSS_PIN, OUTPUT);
pinMode(SPU_TEST_PIN, OUTPUT);
pinMode(SPU_HOLD_PIN, OUTPUT);
pinMode(LED_STATUS, OUTPUT);
pinMode(LED_LIMIT, OUTPUT);
//Set initial values.
digitalWrite(SPU_NSS_PIN, HIGH);
digitalWrite(SPU_TEST_PIN, HIGH);
digitalWrite(SPU_HOLD_PIN, LOW);
//Start of operation. (Flash LED's).
Serial.print("Device reset.\n\r");
digitalWrite(LED_STATUS, HIGH);
digitalWrite(LED_LIMIT, HIGH);
delay(200);
digitalWrite(LED_STATUS, LOW);
digitalWrite(LED_LIMIT, LOW);
delay(200);
//Configure SPU.
COM_SPI(SPU_SET_PRESCALAR_6MHz);
COM_SPI(SPU_SET_CHANNEL_1);
COM_SPI(SPU_SET_BAND_PASS_FREQUENCY);
COM_SPI(SPU_SET_PROGRAMMABLE_GAIN);
COM_SPI(SPU_SET_INTEGRATOR_TIME);
}
//Main operation function.
void loop() {
//Infinite loop.
while (1) {
//Set status LED on, operation starts.
digitalWrite(LED_STATUS, HIGH);
//The measurement window starts by driving digital pin 4 high.
digitalWrite(SPU_HOLD_PIN, HIGH);
//The SPU performs the integration process and increases the output voltage based on the signal processing result.
delayMicroseconds(MEASUREMENT_WINDOW_TIME);
//The measurement window ends by driving digital pin 4 low. The SPU stops the integration process and the output voltage is frozen until the window starts again.
digitalWrite(SPU_HOLD_PIN, LOW);
//The SPU output voltage is read by the Arduino ADC on analogue input pin 0.
uint16_t adcValue_UA = analogRead(UA_ANALOG_INPUT_PIN);
//Convert ADC-value to percentage.
float knock_percentage = ((float)adcValue_UA / 1023) * 100;
//Set Limit LED if knock percentage reaches 80%.
if (knock_percentage >= 80) digitalWrite(LED_LIMIT, HIGH); else digitalWrite(LED_LIMIT, LOW);
//Display oxygen content.
Serial.print("SPU KNOCK LEVEL: ");
Serial.print(knock_percentage, 0);
Serial.print("%\n\r");
//Set status LED off, operation stops. Inlcuding additional delay time for visibility.
delay(100);
digitalWrite(LED_STATUS, LOW);
//Delay to update serial output every ~500ms.
delay(400);
}
}