Skip to content

Commit c44caee

Browse files
committed
Content update (assets)
1 parent 5ae5c77 commit c44caee

File tree

8 files changed

+80
-44
lines changed

8 files changed

+80
-44
lines changed
Loading
Loading
Loading
Loading
Loading
1.06 MB
Loading
Loading

content/hardware/03.nano/boards/nano-r4/tutorials/02.anomaly-detection-application-note/content.md

Lines changed: 80 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -152,15 +152,21 @@ const int xPin = A0;
152152
const int yPin = A1;
153153
const int zPin = A2;
154154
155-
// ADXL335 specifications
156-
const float sensitivity = 0.330; // 330 mV/g
157-
const float zeroG = 1.65; // 1.65V at 0g
158-
const float vRef = 3.3; // Reference voltage
155+
// Arduino ADC specifications
156+
const int ADCMaxVal = 16383; // 14-bit ADC max value
157+
const float mVMaxVal = 5000.0; // ADC reference voltage in mV
158+
159+
// ADXL335 specifications (calibrated values for this specific breakout board)
160+
const float supplyMidPointmV = 1237.0; // Measured 0g bias point
161+
const float mVperg = 303.0; // Measured sensitivity (mV/g)
159162
160163
// Sampling parameters
161-
const int sampleRate = 100; // 100 Hz
164+
const int sampleRate = 100; // 100 Hz
162165
const unsigned long sampleTime = 1000 / sampleRate; // 10ms between samples
163166
167+
// Conversion factor from ADC to mV
168+
const float mVPerADC = mVMaxVal / ADCMaxVal;
169+
164170
// Data collection variables
165171
unsigned long lastSample = 0;
166172
@@ -179,20 +185,20 @@ void loop() {
179185
unsigned long currentTime = millis();
180186
181187
if (currentTime - lastSample >= sampleTime) {
182-
// Read raw values
188+
// Read raw ADC values
183189
int xRaw = analogRead(xPin);
184190
int yRaw = analogRead(yPin);
185191
int zRaw = analogRead(zPin);
186192
187-
// Convert to voltages
188-
float xVolt = (xRaw * vRef) / 16383.0;
189-
float yVolt = (yRaw * vRef) / 16383.0;
190-
float zVolt = (zRaw * vRef) / 16383.0;
193+
// Convert ADC values to millivolts
194+
float xVoltmV = xRaw * mVPerADC;
195+
float yVoltmV = yRaw * mVPerADC;
196+
float zVoltmV = zRaw * mVPerADC;
191197
192-
// Convert to acceleration (g)
193-
float xAccel = (xVolt - zeroG) / sensitivity;
194-
float yAccel = (yVolt - zeroG) / sensitivity;
195-
float zAccel = (zVolt - zeroG) / sensitivity;
198+
// Convert to acceleration in g units
199+
float xAccel = (xVoltmV - supplyMidPointmV) / mVperg;
200+
float yAccel = (yVoltmV - supplyMidPointmV) / mVperg;
201+
float zAccel = (zVoltmV - supplyMidPointmV) / mVperg;
196202
197203
// Output CSV format
198204
Serial.print(xAccel, 4);
@@ -223,16 +229,25 @@ const int xPin = A0;
223229
const int yPin = A1;
224230
const int zPin = A2;
225231
226-
// ADXL335 specifications
227-
const float sensitivity = 0.330; // 330 mV/g
228-
const float zeroG = 1.65; // 1.65V at 0g
229-
const float vRef = 3.3; // Reference voltage
232+
// Arduino ADC specifications
233+
const int ADCMaxVal = 16383; // 14-bit ADC max value
234+
const float mVMaxVal = 5000.0; // ADC reference voltage in mV
235+
236+
// ADXL335 specifications (calibrated values for this specific breakout board)
237+
const float supplyMidPointmV = 1237.0; // Measured 0g bias point
238+
const float mVperg = 303.0; // Measured sensitivity (mV/g)
239+
240+
// Conversion factor from ADC to mV
241+
const float mVPerADC = mVMaxVal / ADCMaxVal;
230242
```
231243
In this code:
232244

233-
- Pin assignments map each accelerometer axis to specific analog inputs on the Nano R4
234-
- Sensitivity and zero-g voltage values come from the [ADXL335 datasheet](https://www.analog.com/media/en/technical-documentation/data-sheets/adxl335.pdf)
235-
- Reference voltage matches the accelerometer's regulated output voltage
245+
- Pin assignments map each accelerometer axis to specific analog inputs on the Nano R4 board
246+
- ADC specifications define the 14-bit resolution and 5V reference voltage used by the Nano R4
247+
- ADXL335 specifications use calibrated values measured from the actual breakout board
248+
- The conversion factor translates raw ADC readings to millivolts for processing
249+
250+
***__Important note__: ADXL335 breakout boards typically include onboard voltage regulators that convert the input voltage (+5 VDC from the Nano R4) to a lower voltage (usually +3.3 VDC or less) to power the accelerometer chip. This means the actual supply voltage to the ADXL335 may be different from what you expect. The values shown in this code (supplyMidPointmV = 1237.0 and mVperg = 303.0) are calibrated for a specific breakout board and may need adjustment for your hardware.***
236251

237252
### Data Collection Timing and Control
238253

@@ -252,34 +267,36 @@ In this code:
252267

253268
### Signal Processing and Conversion
254269

255-
Once we have the raw sensor readings, we need to convert them into useful acceleration values. This conversion process transforms the ADC readings into data we can analyze:
270+
Once we have the raw sensor readings, we need to convert them into useful acceleration values. This conversion process transforms the ADC readings into calibrated acceleration data:
256271

257272
```arduino
258273
void loop() {
259274
unsigned long currentTime = millis();
260275
261276
if (currentTime - lastSample >= sampleTime) {
262-
// Read raw values
277+
// Read raw ADC values
263278
int xRaw = analogRead(xPin);
264279
int yRaw = analogRead(yPin);
265280
int zRaw = analogRead(zPin);
266281
267-
// Convert to voltages
268-
float xVolt = (xRaw * vRef) / 16383.0;
269-
float yVolt = (yRaw * vRef) / 16383.0;
270-
float zVolt = (zRaw * vRef) / 16383.0;
282+
// Convert ADC values to millivolts
283+
float xVoltmV = xRaw * mVPerADC;
284+
float yVoltmV = yRaw * mVPerADC;
285+
float zVoltmV = zRaw * mVPerADC;
271286
272-
// Convert to acceleration (g)
273-
float xAccel = (xVolt - zeroG) / sensitivity;
274-
float yAccel = (yVolt - zeroG) / sensitivity;
275-
float zAccel = (zVolt - zeroG) / sensitivity;
287+
// Convert to acceleration in g units
288+
float xAccel = (xVoltmV - supplyMidPointmV) / mVperg;
289+
float yAccel = (yVoltmV - supplyMidPointmV) / mVperg;
290+
float zAccel = (zVoltmV - supplyMidPointmV) / mVperg;
276291
```
277292

278293
In this code:
279294

280295
- Timing control maintains consistent sample intervals, which is essential for proper frequency analysis
281-
- ADC conversion uses the Nano R4's 14-bit resolution that ranges from 0 to 16383
282-
- Acceleration calculation applies the ADXL335 calibration parameters to get accurate g-force values
296+
- ADC conversion uses the Nano R4's 14-bit resolution to convert raw readings to millivolts
297+
- Acceleration calculation applies the calibrated zero-point and sensitivity values to get accurate g-force measurements
298+
299+
***__Important note__: For accurate measurements, you should calibrate your specific ADXL335 breakout board by placing it flat on a table with the Z-axis pointing up and measuring the actual voltage outputs. The X and Y axes should read approximately the same voltage (this is your zero-g bias point), while the Z-axis should read higher due to gravity (1g acceleration). The difference between Z-axis voltage and the zero-g bias point gives you the sensitivity in mV/g. This calibration accounts for variations in onboard regulators and manufacturing tolerances.***
283300

284301
### Edge Impulse Data Formatting
285302

@@ -387,9 +404,15 @@ With the data forwarder running, you can now collect training data for your anom
387404

388405
Start by mounting the accelerometer securely to the motor housing. You will collect two types of normal operation data:
389406

390-
1. **Idle data collection**: With the motor turned off, collect 10 to 15 minutes of "idle" operation data through multiple two second windows. This captures the baseline vibration environment without motor operation. Label all data as `idle` in Edge Impulse Studio.
407+
1. **Idle data collection**: With the motor turned off, **collect 10 to 15 minutes of "idle" operation** data through multiple two second windows. This captures the baseline vibration environment without motor operation. Label all data as `idle` in Edge Impulse Studio.
408+
409+
2. **Nominal data collection**: With the motor running under normal operating conditions, **collect 10 to 15 minutes of "nominal" operation** data through multiple two second windows. Vary motor load conditions slightly to capture different normal operating scenarios. Label all data as `nominal` in Edge Impulse Studio.
410+
411+
Edge Impulse can automatically split your collected data into **training (80%) and testing (20%) sets**. The 20 to 30 minutes total of data ensures you have enough samples for both training the model and validating its performance on unseen data.
391412

392-
2. **Nominal data collection**: With the motor running under normal operating conditions, collect 10 to 15 minutes of "nominal" operation data through multiple two second windows. Vary motor load conditions slightly to capture different normal operating scenarios. Label all data as `nominal` in Edge Impulse Studio.
413+
![Data collection on Edge Impulse Studio](assets/data-collection.png)
414+
415+
After data collection, review the collected samples in Edge Impulse Studio for consistency. Check for proper amplitude ranges and no clipping, verify sample rate consistency and timing accuracy and remove any corrupted or unusual samples from the training set.
393416

394417
***__Important note__: The anomaly detection model learns what "normal" looks like from both idle and nominal data. Any future vibration patterns that significantly differ from these learned patterns will be flagged as anomalies. This approach allows the system to detect unknown fault conditions without needing examples of actual motor failures.***
395418

@@ -401,43 +424,56 @@ Once you have collected sufficient `idle` and `nominal` operation data, the nex
401424

402425
Within Edge Impulse Studio, configure the impulse design with appropriate processing and learning blocks. Navigate to the "Impulse design" tab and set up the following blocks:
403426

404-
1. **Input Block**: Configure time series data with 2000 ms windows at 100 Hz sampling rate (200 samples per window)
427+
1. **Input Block**: Configure time series data with window size of 2000 ms, window increase of 80 ms, and frequency of 100 Hz to match your data collection sampling rate.
405428
2. **Processing Block**: Add "Spectral Analysis" block for frequency domain feature extraction
406429
3. **Learning Block**: Select "Anomaly Detection (K-means)" for unsupervised learning approach
407430

431+
![Impulse design on Edge Impulse Studio](assets/impulse-design.png)
432+
408433
#### Feature Extraction Configuration
409434

410435
The spectral analysis block extracts relevant features from the raw vibration signals. Configure the following parameters for optimal motor fault detection:
411436

412-
- **FFT Length**: 256 points for sufficient frequency resolution up to 50 Hz
413-
- **Filter**: Low-pass filter with 50 Hz cutoff to focus on motor fault frequencies
414-
- **Spectral Power Edges**: Define frequency bands covering 0 to 50 Hz for motor characteristics
415-
- **Analysis Type**: Power spectral density for energy-based feature extraction
437+
- **Type**: Low-pass filter to focus on motor fault frequencies
438+
- **Cut-off frequency**: 45 Hz to capture relevant motor vibration characteristics while staying below the Nyquist frequency
439+
- **Order**: 6 for effective filtering
440+
- **FFT length**: 256 points for sufficient frequency resolution
441+
- **Take log of spectrum**: Enable this option to compress the dynamic range of the frequency data
442+
- **Overlap FFT frames**: Enable this option to increase the number of features extracted from each window
443+
444+
![Spectral features on Edge Impulse Studio](assets/spectral-features.png)
416445

417446
***__Important note__: The spectral analysis converts time-domain vibration signals into frequency-domain features. This is crucial because motor faults often appear as specific frequency patterns (like bearing wear creating high-frequency components or imbalance showing up at rotational frequency). The K-means clustering algorithm groups similar frequency patterns together, creating a map of normal operation that can identify when new data doesn't fit the established patterns.***
418447

419448
#### Model Training Process
420449

421450
Follow these steps to train the anomaly detection model using the collected idle and nominal operation data:
422451

423-
1. **Generate Features**: Click "Generate features" to extract spectral features from all training data
424-
2. **Feature Explorer**: Review the feature explorer visualization to verify data quality and feature separation
425-
3. **Anomaly Detection Setup**: Configure K-means clustering with 32 clusters for pattern recognition
452+
1. **Generate Features**: Before clicking "Generate features", enable "Calculate feature importance" to identify which frequency bands are most relevant for distinguishing between idle and nominal states. Then click "Generate features" to extract spectral features from all training data. Edge Impulse will process your data and create the feature vectors needed for training.
453+
2. **Feature Explorer**: Review the feature explorer visualization to verify data quality and feature separation between your idle and nominal classes.
454+
455+
![Feature explorer on Edge Impulse Studio](assets/feature-explorer.png)
456+
457+
3. **Anomaly Detection Setup**: Go to the "Anomaly detection" tab in the left menu to configure the machine learning model.
426458
4. **Axis Selection**: Use "Select suggested axes" to automatically choose the most relevant spectral features
427459
5. **Start Training**: Start the training process and monitor convergence metrics
428460

461+
![Anomaly detection on Edge Impulse Studio](assets/anomaly-detection.png)
462+
429463
***__Important note__: The feature explorer shows how well your idle and nominal data separate in the feature space. Good separation means the model can clearly distinguish between different operating states. If the data points overlap significantly, you may need to collect more diverse data or adjust your sensor mounting.***
430464

431465
The training process creates clusters representing normal motor operation patterns. Any future data that falls outside these established clusters will be identified as anomalous.
432466

467+
![Anomaly explorer on Edge Impulse Studio](assets/anomaly-explorer.png)
468+
433469
***__Important note__: The 32 clusters create a detailed map of normal operation patterns. Each cluster represents a different "type" of normal vibration signature. When new data doesn't fit well into any existing cluster, it's flagged as an anomaly. More clusters provide finer detail but require more training data.***
434470

435471
#### Model Validation and Testing
436472

437473
After training completion, validate the model performance using the following methods:
438474

439475
- **Live Classification**: Test with new motor data to verify anomaly detection capability
440-
- **Threshold Tuning**: Adjust anomaly threshold (typically 0.3-0.5) based on desired sensitivity
476+
- **Threshold Tuning**: Adjust anomaly threshold (typically 0.3 to 0.5) based on desired sensitivity
441477
- **Performance Analysis**: Review clustering quality and feature importance rankings
442478
- **False Alarm Testing**: Validate with known normal conditions to reduce false positives
443479

0 commit comments

Comments
 (0)