Skip to content

Commit 566eac9

Browse files
committed
regular adc reads
1 parent 52fb0b4 commit 566eac9

3 files changed

Lines changed: 92 additions & 1 deletion

File tree

docs/simplefoc_library/practical/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Need more help? Visit the community forum: <a href="https://community.simplefoc.
4040
- [Real-time loop with timers](real_time_loop) - implementing the FOC loop in hard real time.
4141
- [Implementing a custom sensor](generic_sensor) - how to implement a custom sensor class.
4242
- [Implementing a custom current sense](generic_current_sense) - how to implement a custom current-sensing setup.
43+
- [Regular ADC reads during FOC](regular_adc_read) - reading auxiliary analog signals safely while current sensing is active.
4344

4445
## Performance tips
4546

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
---
2+
layout: default
3+
title: Regular ADC reads during FOC
4+
nav_order: 6
5+
description: "Reading extra analog signals while low-side current sensing is running."
6+
permalink: /regular_adc_read
7+
parent: Practical guides
8+
grand_parent: Arduino <span class="simple">Simple<span class="foc">FOC</span>library</span>
9+
toc: true
10+
---
11+
12+
# Regular ADC reads during FOC
13+
14+
Sometimes you want to read extra analog signals (bus voltage, temperature, potentiometers, etc.) while the motor is running with **low‑side current sensing**. On some MCUs, `analogRead()` can interfere with the ADC configuration used for current sensing, or it can be too slow and add jitter. The library provides MCU‑specific helpers that are safe to use during FOC.
15+
16+
## STM32: `_readRegularADCVoltage()`
17+
18+
On STM32, low‑side current sensing uses **injected ADC conversions**. Injected conversions have hardware priority and will pre‑empt regular conversions. The library exposes a helper that performs a **one‑shot regular conversion** while injected conversions are running:
19+
20+
- Implemented as `_readRegularADCVoltage(const int pin)` in the STM32 backend.
21+
- If low‑side current sensing is already running, the ADC is already configured and this function reuses it.
22+
- If the pin belongs to another ADC, it initializes it for regular reads.
23+
- The function retries if the ADC is busy and returns **voltage in volts**.
24+
25+
**Why `analogRead()` is a bad idea on STM32 during FOC**
26+
27+
`analogRead()` can reconfigure the ADC each call and does not account for injected conversions. That can **break the current‑sensing configuration**, add latency, and introduce jitter in the control loop. The STM32 helper is still slower than injected reads (typically >10µs) but **much faster and safer than `analogRead()`**.
28+
29+
**Example (STM32, low‑side current sensing already running)**
30+
31+
```cpp
32+
#include <SimpleFOC.h>
33+
#include "current_sense/hardware_specific/stm32/stm32_mcu.h"
34+
35+
// ... motor + driver setup omitted for brevity
36+
LowSideCurrentSense current_sense = LowSideCurrentSense(0.01f, 50.0f, A0, A1, A2);
37+
38+
void setup() {
39+
// driver + motor init ...
40+
current_sense.init();
41+
current_sense.linkDriver(&driver);
42+
}
43+
44+
void loop() {
45+
motor.loopFOC();
46+
motor.move(target);
47+
48+
// Read an auxiliary ADC pin while low-side current sensing is active
49+
float vbus = _readRegularADCVoltage(A3);
50+
// use vbus...
51+
}
52+
```
53+
54+
**Notes**
55+
- Use a pin that belongs to the same ADC as your current‑sense pins whenever possible.
56+
- If the pin belongs to another ADC, the helper will initialize it for regular reads.
57+
- The first time you call the helper for a new ADC it will be slower due to initialization, but subsequent calls will be faster.
58+
- Call this helper only when necessary (e.g., once per control loop) to avoid excessive overhead.
59+
60+
## ESP32: `adcRead()`
61+
62+
On ESP32, the library provides `adcRead(pin)` for fast ADC access using direct register reads. It is placed in IRAM and is designed to be safe inside fast control loops. This is the preferred way to read extra analog signals while current sensing is active.
63+
64+
**Why `analogRead()` is a bad idea on ESP32 during FOC**
65+
66+
`analogRead()` is slower and can add overhead or modify ADC configuration (attenuation, resolution). The library’s `adcRead()` keeps the conversion path fast and deterministic.
67+
68+
**Example (ESP32)**
69+
70+
```cpp
71+
#include <SimpleFOC.h>
72+
#include "current_sense/hardware_specific/esp32/esp32_adc_driver.h"
73+
74+
const int vbusPin = 34; // ADC pin
75+
76+
void setup() {
77+
adcInit(vbusPin); // configure ADC (attenuation + resolution)
78+
}
79+
80+
void loop() {
81+
// ... FOC loop
82+
uint16_t raw = adcRead(vbusPin); // 0–4095
83+
float vbus = raw * (3.3f / 4096.0f);
84+
// use vbus...
85+
}
86+
```
87+
88+
**Notes**
89+
- Call `adcInit(pin)` once (e.g., in `setup()`), then use `adcRead(pin)` in the loop.
90+
- Call this function as little as possible (e.g., every 10–100ms) to avoid unnecessary overhead in the control loop.

index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Therefore this is an attempt to:
3232
<p class="heading">NEW RELEASE 📢: <span class="simple">Simple<span class="foc">FOC</span>library</span> v2.4.0 <a href="https://github.com/simplefoc/Arduino-FOC/releases/tag/v2.4.0">see release</a></p>
3333

3434
- STM32
35-
- Added support for ADC reads in addition to Lowside current sense [#506](https://github.com/simplefoc/Arduino-FOC/pull/506)
35+
- Added support for ADC reads in addition to Lowside current sense [#506](https://github.com/simplefoc/Arduino-FOC/pull/506) - [see in docs](regular_adc_read)
3636
- Added support for multiple motors low-side CS (one per ADC) with ADC current sensing [#503](https://github.com/simplefoc/Arduino-FOC/pull/503)
3737
- BG341 low-side current sense sync was lost in v2.3.5 - fixed [#482](https://github.com/simplefoc/Arduino-FOC/pull/482)
3838
- ESP32

0 commit comments

Comments
 (0)