Skip to content

Commit 39e6ed5

Browse files
authored
cache lastValue (#6)
- change behaviour - cache lastValue as calculated by **ready()** - change **uint16_t value()** signature - update examples - update GitHub actions - minor edits
1 parent 1247671 commit 39e6ed5

File tree

13 files changed

+155
-83
lines changed

13 files changed

+155
-83
lines changed

.github/FUNDING.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# These are supported funding model platforms
22

3-
github: RobTillaart
3+
github: RobTillaart
4+
custom: "https://www.paypal.me/robtillaart"
45

.github/workflows/arduino-lint.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
21
name: Arduino-lint
32

43
on: [push, pull_request]
54
jobs:
65
lint:
76
runs-on: ubuntu-latest
7+
timeout-minutes: 5
88
steps:
9-
- uses: actions/checkout@v3
9+
- uses: actions/checkout@v4
1010
- uses: arduino/arduino-lint-action@v1
1111
with:
1212
library-manager: update

.github/workflows/arduino_test_runner.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
---
21
name: Arduino CI
32

43
on: [push, pull_request]
54

65
jobs:
76
runTest:
87
runs-on: ubuntu-latest
8+
timeout-minutes: 20
99

1010
steps:
11-
- uses: actions/checkout@v3
11+
- uses: actions/checkout@v4
1212
- uses: ruby/setup-ruby@v1
1313
with:
1414
ruby-version: 2.6

.github/workflows/jsoncheck.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ on:
99
jobs:
1010
test:
1111
runs-on: ubuntu-latest
12+
timeout-minutes: 5
1213
steps:
13-
- uses: actions/checkout@v3
14+
- uses: actions/checkout@v4
1415
- name: json-syntax-check
15-
uses: limitusus/json-syntax-check@v1
16+
uses: limitusus/json-syntax-check@v2
1617
with:
1718
pattern: "\\.json$"
1819

AsyncAnalog.cpp

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// FILE: AsyncAnalog.cpp
33
// AUTHOR: Rob Tillaart
4-
// VERSION: 0.1.6
4+
// VERSION: 0.2.0
55
// DATE: 2018-09-05
66
// PURPOSE: Async version of analogRead, prevent blocking wait
77
// URL: https://github.com/RobTillaart/AsyncAnalog
@@ -26,15 +26,15 @@ AsyncAnalog::AsyncAnalog(const uint8_t pin)
2626
void AsyncAnalog::start()
2727
{
2828
#if defined(ADCSRB) && defined(MUX5)
29-
// the MUX5 bit of ADCSRB selects whether we're reading from channels
30-
// 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
29+
// the MUX5 bit of ADCSRB selects whether we're reading from channels
30+
// 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
3131
ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((_pin >> 3) & 0x01) << MUX5);
3232
#endif
3333

3434
#if defined(ADMUX)
35-
// set the analogue reference (high two bits of ADMUX) and select the
36-
// channel (low 4 bits). this also sets ADLAR (left-adjust result)
37-
// to 0 (the default).
35+
// set the analogue reference (high two bits of ADMUX) and select the
36+
// channel (low 4 bits). this also sets ADLAR (left-adjust result)
37+
// to 0 (the default).
3838
ADMUX = (DEFAULT << 6) | (_pin & 0x07);
3939
#endif
4040

@@ -45,23 +45,31 @@ void AsyncAnalog::start()
4545
bool AsyncAnalog::ready()
4646
{
4747
// ADSC is cleared when the conversion finishes
48-
return bit_is_set(ADCSRA, ADSC) == 0;
48+
bool _ready = bit_is_set(ADCSRA, ADSC) == 0;
49+
50+
if (_ready) // calculate the measurement
51+
{
52+
// ADCL has to be read first.
53+
// Doing so locks both ADCL and ADCH until ADCH is read.
54+
// Reading ADCL second would cause the results of each conversion to
55+
// be discarded as ADCL and ADCH would be locked when it completed.
56+
uint16_t lo = ADCL;
57+
uint16_t hi = ADCH;
58+
// Combine two parts.
59+
_lastValue = (hi * 256) + lo;
60+
}
61+
return _ready;
4962
}
5063

5164

52-
int AsyncAnalog::value()
65+
uint16_t AsyncAnalog::value()
5366
{
54-
// ADCL has to be read first.
55-
// Doing so locks both ADCL and ADCH until ADCH is read.
56-
// Reading ADCL second would cause the results of each conversion to
57-
// be discarded as ADCL and ADCH would be locked when it completed.
58-
uint16_t lo = ADCL;
59-
uint16_t hi = ADCH;
60-
// Combine two parts.
61-
// _lastValue = (hi * 256) + lo;
62-
return (hi * 256) + lo;
67+
return _lastValue;
6368
}
6469

70+
#else
71+
72+
6573
#endif // ARDUINO_ARCH_AVR
6674

6775

AsyncAnalog.h

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,71 @@
22
//
33
// FILE: AsyncAnalog.h
44
// AUTHOR: Rob Tillaart
5-
// VERSION: 0.1.6
5+
// VERSION: 0.2.0
66
// DATE: 2018-09-05
77
// PURPOSE: Async version of analogRead for AVR
88
// URL: https://github.com/RobTillaart/AsyncAnalog
99

1010

11-
#if !defined(ARDUINO_ARCH_AVR)
11+
#define ASYNCANALOG_LIB_VERSION (F("0.2.0"))
1212

13-
#error “AsyncAnalog library only supports boards with an AVR processor .”
1413

15-
#else
16-
17-
// (ARDUINO_ARCH_SAM) future
18-
// (ARDUINO_ARCH_ESP32) future
19-
// (ARDUINO_ARCH_ESP8266) future
14+
#if defined(ARDUINO_ARCH_AVR)
2015

2116

2217
#include "Arduino.h"
2318
#include "wiring_private.h"
2419
#include "pins_arduino.h"
2520

26-
#define ASYNCANALOG_LIB_VERSION (F("0.1.6"))
27-
2821

2922
class AsyncAnalog
3023
{
3124
public:
3225
AsyncAnalog(const uint8_t pin);
3326

34-
void start();
35-
bool ready();
36-
int value();
27+
void start();
28+
bool ready();
29+
uint16_t value();
30+
31+
private:
32+
uint8_t _pin;
33+
uint16_t _lastValue;
34+
};
35+
36+
// #elif defined(ARDUINO_ARCH_SAM)
37+
// #elif defined(ARDUINO_ARCH_ESP32)
38+
// #elif defined(ARDUINO_ARCH_ESP8266)
39+
40+
41+
#else
42+
43+
#error “AsyncAnalog library only supports boards with an AVR processor .”
44+
45+
46+
/*
47+
#include "Arduino.h"
48+
49+
// fall back for other platforms?
50+
51+
class AsyncAnalog
52+
{
53+
public:
54+
AsyncAnalog(const uint8_t pin)
55+
{
56+
_pin = pin;
57+
_lastValue = 0;
58+
}
59+
60+
void start() { _lastValue = analogRead(_pin); };
61+
bool ready() { return true; };
62+
uint16_t value() { return _lastValue; };
3763
3864
private:
3965
uint8_t _pin;
40-
// uint16_t _lastValue;
66+
uint16_t _lastValue;
4167
};
68+
*/
69+
4270

4371
#endif // defined(ARDUINO_ARCH_AVR)
4472

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,21 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

88

9+
## [0.2.0] - 2024-04-06
10+
- change behaviour
11+
- cache lastValue as calculated by **ready()**
12+
- change **uint16_t value()** signature
13+
- update examples
14+
- update GitHub actions
15+
- minor edits
16+
17+
----
18+
919
## [0.1.6] - 2023-10-17
1020
- update readme.md
1121
- add changelog.md
1222
- minor edits
1323

14-
1524
## [0.1.5] - 2021-12-13
1625
- update library.json
1726
- update license

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2018-2023 Rob Tillaart
3+
Copyright (c) 2018-2024 Rob Tillaart
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,31 +17,41 @@ Arduino Library for async reading of an analogue pin. **\[AVR ONLY\]**.
1717
## Description
1818

1919
AsyncAnalog is a library to read the analogue port of an **AVR** in an asynchronous way.
20-
This means that the user must explicitly **start** the ADC, check if it is **ready**
21-
and read out its **value**.
20+
This means that the user must explicitly **start()** the ADC, check if it is **ready()**
21+
and read its **value()**.
2222

2323
By using this class, the user prevents the (~112 uSec) blocking of the
2424
**analogRead()** call, and gives the user the ability to do some processing.
2525

2626
The library works only for AVR boards now, other platforms might be supported in the future.
27+
(PR's are welcome).
2728

2829
**WARNING**
29-
As the UNO has only one ADC that is multiplexed, one can only read one analogue pin
30-
in async way simultaneously.
30+
As the UNO has only one ADC that is multiplexed, one can only read one analog pin
31+
in async way simultaneously. Still it offers to about 100 micros to do something!
3132

3233
**Use with care**
3334

3435

36+
#### Related
37+
38+
- https://github.com/RobTillaart/AnalogPin
39+
40+
3541
## Interface
3642

3743
```cpp
3844
#include "AsynAnalog,h"
3945
```
4046

4147
- **AsyncAnalog(uint8_t pin)** constructor, defines the analogue pin to use.
42-
- **void start()** triggers a new ADC reading.
43-
- **bool ready()** returns true if sample is complete.
44-
- **int value()** returns the value.
48+
- **void start()** triggers a new ADC measurement.
49+
- **bool ready()** Checks if the measurement is completed.
50+
If so the value is calculated and cached for **value()**.
51+
As long as ready() is not called the old value will not change!
52+
- **uint16_t value()** returns the value of the ADC from cache.
53+
So it will return the same value even if the internal ADC is used to sample
54+
another analog port.
4555

4656

4757
## Operation
@@ -54,18 +64,22 @@ over Serial at 115200 baud.
5464

5565
#### Must
5666

67+
- improve documentation.
68+
5769
#### Should
5870

59-
- improve documentation.
71+
- create examples
72+
- real world examples preferred.
73+
- multi ADC, e.g. A0..A4
74+
6075

6176
#### Could
6277

6378
- investigate the performance gain.
6479
- asyncAnalogTest2.ino is not a good test.
65-
- create examples
66-
- real world examples preferred.
6780
- investigate other platforms
6881
- fall back to normal analogRead for non AVR platforms ?
82+
- start would be analogRead() and it would immediately be ready and the value is cached.
6983
- better have specific code per platform.
7084

7185
#### Wont
Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
//
22
// FILE: asyncAnalogTest.ino
33
// AUTHOR: Rob Tillaart
4-
// VERSION: 0.1.1
5-
// DATE: 2018-09-05
4+
// PURPOSE: demo
65

76

87
#include "AsyncAnalog.h"
@@ -18,9 +17,14 @@ uint16_t count = 0;
1817
void setup()
1918
{
2019
Serial.begin(115200);
21-
Serial.println("start: ");
20+
Serial.println(__FILE__);
21+
Serial.print("ASYNCANALOG_LIB_VERSION: ");
22+
Serial.println(ASYNCANALOG_LIB_VERSION);
23+
24+
Serial.print("\nstart: ");
2225
Serial.println(analogRead(0));
2326

27+
// request initial measurement
2428
AA.start();
2529
start = micros();
2630
}
@@ -29,29 +33,31 @@ void setup()
2933
void loop()
3034
{
3135

32-
// if sample ready
36+
// if measurement ready
3337
if (AA.ready())
3438
{
35-
// process sample
39+
// get data
3640
duration = micros() - start;
41+
uint16_t val = AA.value();
3742

43+
// process measurement
3844
Serial.print(duration);
39-
Serial.print("\t");
40-
Serial.print(AA.value());
41-
Serial.print("\t");
42-
Serial.print(count);
43-
Serial.println();
45+
Serial.print('\t');
46+
Serial.print(val);
47+
Serial.print('\t');
48+
Serial.println(count);
4449

45-
// request a new sample
50+
// request a new measurement
4651
AA.start();
4752
start = micros();
53+
54+
4855
count = 0;
4956
}
5057

51-
// do other stuff here
58+
// do other stuff here
5259
count++;
5360
}
5461

5562

56-
// -- END OF FILE --
57-
63+
// -- END OF FILE --

0 commit comments

Comments
 (0)