ArduinoNative

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | LICENSE

commit 582e8bffc5a1961bd368052ed566e20078612bc5
parent 4c178f9549d00f27c9d00b340919433c7b6584d6
Author: Samdal <samdal@protonmail.com>
Date:   Sun,  4 Jul 2021 01:01:19 +0200

completed arduino library, analogreference example

Diffstat:
MArduinoNative.hpp | 121++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
MREADME.org | 69++++++++++++++++++++++++++++++++++++++++++---------------------------
2 files changed, 156 insertions(+), 34 deletions(-)

diff --git a/ArduinoNative.hpp b/ArduinoNative.hpp @@ -8,6 +8,7 @@ #include <cmath> #include <chrono> #include <iostream> +#include <stdio.h> #include <iomanip> #include <sstream> #include <string> @@ -17,6 +18,8 @@ /* CONSTANTS */ #define LOW 0 #define HIGH 1 +#define MSBFIRST 0 +#define LSBFIRST 1 typedef enum { INPUT, OUTPUT, @@ -38,6 +41,13 @@ typedef enum { SKIP_WHITESPACE, SKIP_ALL, } LookaheadMode; +typedef enum { + DEFAULT, + INTERNAL, + INTERNAL1V1, + INTERNAL2V56, + EXTERNAL, +} an_reference_t; #define byte uint8_t #define word uint16_t @@ -90,9 +100,10 @@ enum { /* ↑ Arduino UNO ↑ */ #endif -// pin voltages +#define AREF 255 float an_pin_voltage[AN_MAX_PINS] = {0}; + /* FUNCTION DEFINITIONS */ // non-arduino functions @@ -105,10 +116,16 @@ void pinMode(const uint8_t pin, const an_pin_mode_t mode); // Analog I/O uint16_t analogRead(const uint8_t pin); -// void analogReference(); +void analogReference(an_reference_t type); void analogWrite(const uint8_t pin, const uint8_t value); // Advanced I/O +void noTone(const uint8_t pin); +unsigned long pulseIn(const uint8_t pin, const bool val, const unsigned long timeout); +unsigned long pulseInLong(const uint8_t pin, const bool val, const unsigned long timeout); +uint8_t shiftIn(const uint8_t data_pin, const uint8_t clock_pin, const bool bit_order); +void shiftOut(const uint8_t data_pin, const uint8_t clock_pin, const bool bit_order, const byte value); +void tone(const uint8_t pin, unsigned hz, unsigned long dur = 0); //Time inline void delay(const unsigned long milliseconds); @@ -117,10 +134,10 @@ unsigned long micros(void); unsigned long millis(void); // Math +#define constrain(x, a, b) ({x = x < a ? a : x; x = x > b ? b : x;}) #define map(x, fL, fH, tL, tH) ((x - fL) * (tH - tL) / (fH - fL) + tL) #define min(a,b) ((a)<(b)?(a):(b)) #define max(a,b) ((a)>(b)?(a):(b)) -#define constrain(x, low, top) (max(min(x, low), top)) #define sq(x) ((x)*(x)) // Characthers @@ -276,6 +293,7 @@ typedef struct an_int { } an_int_t; std::unordered_map<uint8_t, an_int_t> an_ints; bool an_interrupts_enabled = true; +float an_reference_v = 5.0; void setup(void); void loop(void); @@ -297,7 +315,8 @@ private: buffer.erase(buffer.begin()); continue; } - if ((c == '-') || (c >= '0' && c <= '9') || (is_float && c == '.')) + if ((c == '-') || (c >= '0' && c <= '9') || + (is_float && c == '.')) return true; switch (lookahead) { case SKIP_ALL: @@ -314,7 +333,8 @@ private: { while(available()) { char c = peek(); - if ((c == '-') || (c >= '0' && c <= '9') || (is_float && c == '.')) + if ((c == '-') || (c >= '0' && c <= '9') || + (is_float && c == '.')) buffer.erase(buffer.begin()); else return; @@ -438,7 +458,7 @@ int main() /* ArduinoNative reused functions */ void an_is_pin_defined(uint8_t pin, an_pin_types_t type) { - if (pin > AN_MAX_PINS) { + if (pin > AN_MAX_PINS && pin != AREF) { std::cout << "ERROR: PIN " << std::to_string(pin) << " IS NOT DEFINED\n"; exit(1); } @@ -480,7 +500,7 @@ void pinMode(uint8_t pin, an_pin_mode_t mode) uint16_t analogRead(uint8_t pin) { an_is_pin_defined(pin); - uint16_t val = (uint16_t)lround(map(an_pin_voltage[pin], 0.0f, 5.0f, 0, 1023)); + uint16_t val = (uint16_t)lround(map(an_pin_voltage[pin], 0.0f, an_reference_v, 0, 1023)); val = constrain(val, 0, 1023); #ifdef AN_DEBUG_ANALOGREAD an_print_timestamp(); @@ -499,11 +519,36 @@ void analogWrite(uint8_t pin, uint8_t val) #endif } +void analogReference(an_reference_t type) +{ + switch(type) { + case DEFAULT: + an_reference_v = 5.0; + break; + case INTERNAL: + an_reference_v = 1.1; + break; + case INTERNAL1V1: + an_reference_v = 1.1; + break; + case INTERNAL2V56: + an_reference_v = 2.56; + break; + case EXTERNAL: + break; + } +} + void an_set_voltage(uint8_t pin, float voltage) { an_is_pin_defined(pin); bool is_on = an_pin_voltage[pin] > 3; bool turn_on = voltage > 3; + if (pin == AREF) { + an_reference_v = voltage; + return; + } + /* If pin has interrupt attached */ if (an_interrupts_enabled && an_ints.find(pin) != an_ints.end()) @@ -574,6 +619,68 @@ void detachInterrupt(const uint8_t pin) void interrupts() {an_interrupts_enabled = true;} void noInterrupts() {an_interrupts_enabled = false;} +// Advanced I/O +inline void noTone(const uint8_t pin) +{ +#ifndef _WIN32 + system("killall \"ffplay\" -q"); +#endif +} +unsigned long pulseIn(const uint8_t pin, const bool val, const unsigned long timeout) +{ + while (digitalRead(pin) != val); + unsigned long before = micros(); + while (digitalRead(pin) == val && (!timeout && micros() - before >= timeout)); + unsigned long after = micros(); + return after - before; +} +inline unsigned long pulseInLong(const uint8_t pin, const bool val, const unsigned long timeout) +{ + return pulseIn(pin, val, timeout); +} +uint8_t shiftIn(const uint8_t data_pin, const uint8_t clock_pin, const uint8_t bit_order) +{ + uint8_t value = 0; + uint8_t i; + + for (i = 0; i < 8; ++i) { + digitalWrite(clock_pin, HIGH); + if (bit_order == LSBFIRST) + value |= digitalRead(data_pin) << i; + else + value |= digitalRead(data_pin) << (7 - i); + digitalWrite(clock_pin, LOW); + } + return value; +} +void shiftOut(const uint8_t data_pin, const uint8_t clock_pin, const bool bit_order, byte val) +{ + uint8_t i; + + for (i = 0; i < 8; i++) { + if (bit_order == LSBFIRST) { + digitalWrite(data_pin, val & 1); + val >>= 1; + } else { + digitalWrite(data_pin, (val & 128) != 0); + val <<= 1; + } + + digitalWrite(clock_pin, HIGH); + digitalWrite(clock_pin, LOW); + } +} +void tone(const uint8_t pin, unsigned hz, unsigned long dur) +{ +#ifndef _WIN32 + noTone(pin); + hz = constrain(hz, 0, 20000); + char ffplay[70]; + snprintf(ffplay, sizeof(ffplay), "ffplay -f lavfi -i \"sine=frequency=%d\" -nodisp -loglevel quiet &", hz); + system(ffplay); +#endif +} + #undef AN_IMPL #endif // AN_IMPL diff --git a/README.org b/README.org @@ -43,18 +43,6 @@ If no board is defined it will default to Arduino Uno ** Implemented from Arduino library [[https://www.arduino.cc/reference/en/][Arduino Library Reference]]. Note that less used functions haven't been tested that much. -*** Unfinished / not implemented -- [-] Analog I/O - + [X] analogRead() - + [X] analogWrite() - + [ ] analogReference() -- [ ] Advanced I/O - + [ ] noTone() - + [ ] pulsing) - + [ ] pulseInLong() - + [ ] shiftIn() - + [ ] shiftOut() - + [ ] tone() *** Exceptions - HIGH and LOW interrupt modes don’t work, only CHANGE, RISING and FALLING - serialEvent() is only supported on GCC and Clang, as it uses a GCC extension. @@ -88,16 +76,18 @@ Debug features can be enabled by defining the following macros - *AN_DEBUG_ANALOGREAD*: Prints a message to console when analogRead is called - *AN_DEBUG_ANALOGWRITE*: Prints a message to console when analogWrite is called * Roadmap -- B̶a̶s̶i̶c̶ ̶f̶u̶n̶c̶t̶i̶o̶n̶a̶l̶i̶t̶y̶ -- D̶e̶b̶u̶g̶ ̶o̶p̶t̶i̶o̶n̶s̶ -- m̶o̶r̶e̶ ̶c̶o̶m̶p̶l̶e̶t̶e̶ ̶f̶u̶n̶c̶t̶i̶o̶n̶a̶l̶i̶t̶y̶ -- W̶i̶n̶d̶o̶w̶s̶ ̶s̶u̶p̶p̶o̶r̶t̶ -- S̶e̶r̶i̶a̶l̶ ̶f̶u̶l̶l̶ ̶f̶u̶n̶c̶t̶i̶o̶n̶a̶l̶i̶t̶y̶ -- S̶t̶r̶i̶n̶g̶ ̶o̶b̶j̶e̶c̶t̶ -- Complete rest of Arduino Library -- Support more boards -- Debug schedules -- Debug viewer to show pin status instead of Serial +- [X] Basic functionality +- [X] Debug options +- [X] more complete functionality +- [X] Windows support +- [X] Serial full functionality +- [X] String object +- [X] Complete rest of Arduino Library +- [ ] Support for attaching simulated hardware on pins +- [ ] Attach sine and square(with duty cycle) waves to pins +- [ ] Debug viewer to show pin status instead of Serial +- [ ] Support more boards +- [ ] Implement extra libraries (Servo.h, FastLED, etc) * More examples ** Serial and AnalogRead #+BEGIN_SRC C++ @@ -224,6 +214,9 @@ unsigned short count; void interrupt() { +#ifdef ArduinoNative + an_print_timestamp(); +#endif Serial.print("INTERRUPT"); Serial.println(count); } @@ -250,9 +243,31 @@ void loop() { #+END_SRC Output: #+BEGIN_SRC -INTERRUPT0 -INTERRUPT1 -INTERRUPT2 -INTERRUPT3 -INTERRUPT4 +1000ms | INTERRUPT0 +2000ms | INTERRUPT1 +3000ms | INTERRUPT2 +4000ms | INTERRUPT3 +5000ms | INTERRUPT4 +#+END_SRC +** AnalogReference() +#+BEGIN_SRC C++ +#define AN_IMPL +#include "ArduinoNative.hpp" + +void setup() +{ + Serial.begin(9600); + analogReference(EXTERNAL); +#ifdef ArduinoNative + an_set_voltage(AREF, 3.3); + an_set_voltage(A2, 1.65); +#endif + Serial.println(analogRead(A2)); +} + +void loop() {} +#+END_SRC +Output: +#+BEGIN_SRC +512 #+END_SRC