commit 7c6b4e30282b90aabf6ccc08cc56c5f20dd121a5
parent 8abf548b45b6ad2c5b31b5b01cfa198b396705b0
Author: Samdal <samdal@protonmail.com>
Date: Mon, 21 Jun 2021 22:12:42 +0200
Initial upload from computer
Diffstat:
A | .gitignore | | | 5 | +++++ |
A | ArduinoNative.hpp | | | 356 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | README.org | | | 196 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | test.cpp | | | 17 | +++++++++++++++++ |
4 files changed, 574 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,5 @@
+tmp/
+*.exe
+bin/
+*.out
+*.o
diff --git a/ArduinoNative.hpp b/ArduinoNative.hpp
@@ -0,0 +1,356 @@
+#ifndef ArduinoNative
+#define ArduinoNative
+
+#include <iostream>
+#include <algorithm>
+#include <sstream>
+#include <chrono>
+#include <thread>
+#include <stdint.h>
+#include <cstring>
+#include <cstdlib>
+#include <ctype.h>
+#include <cmath>
+#include <string>
+
+/* CONSTANTS */
+#define String std::string
+#define LOW 0
+#define HIGH 1
+enum {
+ INPUT,
+ OUTPUT,
+ INPUT_PULLUP
+} an_pin_mode;
+
+#define byte uint8_t
+#define word uint16_t
+
+/* DEBUG MESSAGES */
+#ifdef AN_DEBUG_ALL
+#define AN_DEBUG_DIGITALREAD
+#define AN_DEBUG_DIGITALWRITE
+#define AN_DEBUG_ANALOGREAD
+#define AN_DEBUG_ANALOGWRITE
+#endif
+
+/* BOARD DEFINITIONS */
+#if defined(AN_BOARD_NANO) || defined(AN_BOARD_PRO_MINI)
+
+#define MAX_PINS 21
+
+#define LED_BUILTIN 13
+#define A0 14
+#define A1 15
+#define A2 16
+#define A3 17
+#define A4 18
+#define A5 19
+#define A6 20
+#define A7 21
+
+#else // Default is Arduino Uno
+
+#define MAX_PINS 19
+
+#define LED_BUILTIN 13
+#define A0 14
+#define A1 15
+#define A2 16
+#define A3 17
+#define A4 18
+#define A5 19
+
+#endif
+
+uint8_t an_pin_cycle[MAX_PINS] = {0};
+float an_pin_voltage[MAX_PINS] = {0};
+
+/* FUNCTION DEFINITIONS */
+
+// Digital I/O
+bool digitalRead(uint8_t pin);
+void digitalWrite(uint8_t pin, bool value);
+#define pinMode(pin, mode)
+
+// Analog I/O
+uint16_t analogRead(uint8_t pin);
+// void analogReference();
+void analogWrite(uint8_t pin, uint8_t value);
+void an_set_voltage(uint8_t pin, float voltage);
+
+// Zero, Due & MKR Family
+
+// Advanced I/O
+// void noTone(uint8_t pin);
+// unsigned long pulseIn(uint8_t pin, bool value);
+// unsigned long pulseInLong(uint8_t pin, bool value);
+// unsigned long tone(uint8_t pin, unsigned frequenzy);
+
+//Time
+void delay(unsigned long milliseconds);
+void delayMicroseconds(unsigned long microseconds);
+unsigned long micros(void);
+unsigned long millis(void);
+
+// Math
+#define constrain(x, a, b) ({x < a ? a : x; x > b ? b : x;})
+#define map(x, fL, fH, tL, tH) (lround((x - fL) * (tH - tL) / (fH - fL) + tL))
+#define max(a, b) (a > b ? a : b)
+#define min(a, b) (a < b ? a : b)
+#define sq(x) (x*x)
+// the rest are included in math.h
+// the same with all of the trigonomitry functions
+
+// Characthers
+inline bool isAlpha(char thisChar);
+inline bool isAlphaNumeric(char thisChar);
+inline bool isAscii(char thisChar);
+inline bool isControl(char thisChar);
+inline bool isDigit(char thisChar);
+inline bool isGraph(char thisChar);
+inline bool isHexadecimalDigit(char thisChar);
+inline bool isLowerCase(char thisChar);
+inline bool isPrintable(char thisChar);
+inline bool isPunct(char thisChar);
+inline bool isSpace(char thisChar);
+inline bool isUpperCase(char thisChar);
+inline bool isWhitespace(char thisChar);
+
+// Random Numbers
+inline long random(long max);
+inline long random(long min, long max);
+inline void randomSeed(unsigned long seed);
+
+// Bits and Bytes
+#define bit(n) (1 << n)
+#define bitClear(x, n) (x & ~(1 << n))
+#define bitRead(x, n) (x & (1 << n))
+#define bitSet(x, n) (x |= (1 << n))
+#define bitWrite(x, n, b) (x = ((x & ~(1 << n)) | (b << n)))
+#define highByte(x) ((uint8_t) ((x) >> 8))
+#define lowByte(x) ((uint8_t) ((x) & 0xff))
+
+// External Interrupts
+
+// Interrupts
+
+// Implimentation
+#ifdef AN_IMPL
+
+// Communication
+class an_serial
+{
+private:
+ std::string buffer;
+public:
+ void an_take_input()
+ {
+ std::cout << "ArduinoNative is requesting Serial input: ";
+ std::cin >> buffer;
+ }
+
+ inline size_t available() {return buffer.length();}
+ inline size_t availableForWrite() {return SIZE_MAX;}
+ inline void begin(unsigned speed) {}
+ inline void begin(unsigned speed, int config) {}
+ inline void end() {}
+ inline void flush() {}
+ inline void setTimeout(long new_time) {}
+ int peek()
+ {
+ std::string buffrev = buffer;
+ std::reverse(buffrev.begin(), buffrev.end());
+ return buffrev.length() > 0 ? int(buffrev.back()) : 0;
+ }
+ int read()
+ {
+ std::string buffrev = buffer;
+ std::reverse(buffrev.begin(), buffrev.end());
+ int readByte = buffrev.length() > 0 ? int(buffrev.back()) : 0;
+ buffrev.pop_back();
+ std::reverse(buffrev.begin(), buffrev.end());
+ buffer = buffrev;
+ return readByte;
+ }
+ size_t readBytes(char readbuffer[], unsigned length)
+ {
+ std::stringstream buff;
+ for (; length != 0; length--) {
+ if (!this->available())
+ break;
+ buff << (char)this->read();
+ }
+ std::strcpy(readbuffer, buff.str().c_str());
+ return buff.str().length();
+ }
+ size_t readBytesUntill(char readbuffer[], unsigned length)
+ {
+ std::stringstream buff;
+ for (; length != 0; length--) {
+ if (!this->available())
+ break;
+ buff << (char)this->read();
+ }
+ std::strcpy(readbuffer, buff.str().c_str());
+ return buff.str().length();
+ }
+ //float parseFloat() {}
+ template <typename T>
+ size_t print(T val)
+ {
+ std::cout << val;
+ std::stringstream s;
+ s << val;
+ return s.str().length();
+ }
+ template <typename T>
+ size_t println(T val)
+ {
+ std::cout << val << std::endl;
+ std::stringstream s;
+ s << val;
+ return s.str().length() + 1;
+ }
+};
+
+void setup();
+void loop();
+
+unsigned long an_start_time_ms;
+unsigned long an_start_time_µs;
+an_serial Serial;
+
+// start program
+int main()
+{
+ // Initialize
+ an_start_time_ms = millis();
+ an_start_time_µs = micros();
+
+ // run setup() and loop()
+ setup();
+ for (;;) {
+ loop();
+ }
+}
+
+// Digital I/O
+bool digitalRead(uint8_t pin)
+{
+ if (pin > MAX_PINS) {
+ std::cout << "ERROR: PIN " << std::to_string(pin) << " IS NOT DEFINED\n";
+ exit(1);
+ }
+#ifdef AN_DEBUG_DIGITALREAD
+ std::cout << "Read pin: " << std::to_string(pin) << " is " << std::to_string(an_pin_voltage[pin] > 3) << "\n";
+#endif
+ return an_pin_voltage[pin] > 3;
+}
+
+void digitalWrite(uint8_t pin, bool val)
+{
+ if (pin > MAX_PINS) {
+ std::cout << "ERROR: PIN " << std::to_string(pin) << " IS NOT DEFINED\n";
+ exit(1);
+ }
+ an_pin_cycle[pin] = val * 255;
+ an_pin_voltage[pin] = val * 5.0;
+#ifdef AN_DEBUG_DIGITALWRITE
+ std::cout << "Pin: " << std::to_string(pin) << " is now " << std::to_string(an_pin_voltage[pin] > 3) << "\n";
+#endif
+}
+
+// Analog I/O
+uint16_t analogRead(uint8_t pin)
+{
+ if (pin > MAX_PINS) {
+ std::cout << "ERROR: PIN " << pin << " IS NOT DEFINED\n";
+ exit(1);
+ }
+ uint16_t val = map(an_pin_voltage[pin], 0.0, 5.0, 0, 1023);
+ val = constrain(val, 0, 1023);
+#ifdef AN_DEBUG_ANALOGREAD
+ std::cout << "Analog pin: " << std::to_string(pin) << " is " << std::to_string(val) << "\n";
+#endif
+ return val;
+}
+
+void analogWrite(uint8_t pin, uint8_t val)
+{
+ if (pin > MAX_PINS) {
+ std::cout << "ERROR: PIN " << pin << " IS NOT DEFINED\n";
+ exit(1);
+ }
+ val = constrain(val, 0, 255);
+ an_pin_cycle[pin] = val;
+ an_pin_voltage[pin] = map(val, 0, 255, 0.0, 5.0);
+#ifdef AN_DEBUG_ANALOGWRITE
+ std::cout << "Duty cycle on pin: " << std::to_string(pin) << " is now " << std::to_string(an_pin_cycle[pin]) << "\n";
+#endif
+}
+
+void an_set_voltage(uint8_t pin, float voltage)
+{
+ if (pin > MAX_PINS) {
+ std::cout << "ERROR: PIN " << std::to_string(pin) << " IS NOT DEFINED\n";
+ exit(1);
+ }
+ an_pin_voltage[pin] = voltage;
+}
+
+void an_request_voltage(uint8_t pin)
+{
+ if (pin > MAX_PINS) {
+ std::cout << "ERROR: PIN " << std::to_string(pin) << " IS NOT DEFINED\n";
+ exit(1);
+ }
+ std::cout << "set voltage of pin " << std::to_string(pin) << " to: ";
+ std::cin >> an_pin_voltage[pin];
+}
+
+// Time
+void delay(unsigned long milliseconds)
+{
+ std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
+}
+void delayMicroseconds(unsigned long microseconds)
+{
+ std::this_thread::sleep_for(std::chrono::microseconds(microseconds));
+}
+
+unsigned long micros()
+{
+ auto duration = std::chrono::system_clock::now().time_since_epoch();
+ return std::chrono::duration_cast<std::chrono::microseconds>(duration).count() - an_start_time_µs;
+}
+unsigned long millis()
+{
+ auto duration = std::chrono::system_clock::now().time_since_epoch();
+ return std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() - an_start_time_ms;
+}
+
+// Characters
+bool isAlpha(char thisChar) {return isalpha(thisChar);}
+bool isAlphaNumeric(char thisChar) {return isalnum(thisChar);}
+bool isAscii(char thisChar) {return true;}
+bool isControl(char thisChar) {return iscntrl(thisChar);}
+bool isDigit(char thisChar) {return isdigit(thisChar);}
+bool isGraph(char thisChar) {return isgraph(thisChar);}
+bool isHexadecimalDigit(char thisChar) {return isxdigit(thisChar);}
+bool isLowerCase(char thisChar) {return islower(thisChar);}
+bool isPrintable(char thisChar) {return isprint(thisChar);}
+bool isPunct(char thisChar) {return ispunct(thisChar);}
+bool isSpace(char thisChar) {return isspace(thisChar);}
+bool isUpperCase(char thisChar) {return isupper(thisChar);}
+bool isWhitespace(char thisChar) {return isspace(thisChar);}
+
+// Random Numbers
+long random(long max) {return rand() % max;}
+long random(long min, long max) {return min + rand() % (max - min);}
+void randomSeed(long seed) {srand(seed);}
+
+#undef AN_IMPL
+#endif // AN_IMPL
+
+#endif // ArduinoNative
diff --git a/README.org b/README.org
@@ -0,0 +1,196 @@
+#+TITLE: ArduinoNative
+#+AUTHOR: Halvard Samdal
+
+* What is ArduinoNative?
+Arduino native allows you to run arduino code without arduino.
+ArduinoNative does not attempt to emulate or simulate arduino, it is a simple header only implementation of the Arduino library in order to test and debug arduino code.
+Not only do you have the ability to use your favorite IDE with fancy code suggestions, you can even use a debugger to step through your code.
+* Getting started
+1. Download and install requiered tools to build C++ on your machine
+2. Create a new C++ project and place ArduinoNative.hpp in that directory
+3. Define AN_IMPL in one and only one of your source files
+4. Include ArduinoNative.hpp
+** A basic blink example
+#+BEGIN_SRC C++
+#define AN_DEBUG_AL
+#define AN_IMPL
+#include "ArduinoNative.hpp"
+
+void setup()
+{
+ pinMode(LED_BUILTIN, OUTPUT);
+}
+
+void loop()
+{
+ digitalWrite(LED_BUILTIN, HIGH);
+ delay(1000);
+ digitalWrite(LED_BUILTIN, LOW);
+ delay(1000);
+}
+#+END_SRC
+* Available functions
+Note that some functions are not implemented exactly like Arduino has them.
+For example Serial.print and prinln don't have can't print in byte representation yet.
+** Implimented from Arduino Library:
+Note that less important functions haven't been tested that much
+- [X] Digital I/O()
+ + [X] digitalRead()
+ + [X] digitalWrite()
+ + [X] pinMode()
+- [-] Analog I/O
+ + [X] analogRead()
+ + [X] analogWrite()
+ + [ ] analogReference()
+- [ ] Advanced I/O
+ + [ ] noTone()
+ + [ ] pulseIn()
+ + [ ] pulseInLong()
+ + [ ] shiftIn()
+ + [ ] shiftOut()
+ + [ ] tone()
+- [X] Time
+ + [X] delay()
+ + [X] delayMicroseconds()
+ + [X] micros()
+ + [X] millis()
+- [X] Math
+ + [X] abs()
+ + [X] constrain()
+ + [X] map()
+ + [X] max()
+ + [X] min()
+ + [X] pow()
+ + [X] sq()
+ + [X] sqrt()
+- [X] Trigonometry
+ + [X] cos()
+ + [X] sin()
+ + [X] tan()
+- [X] Characters
+ + [X] isAlpha()
+ + [X] isAlphaNumeric()
+ + [X] isAscii()
+ + [X] isControl()
+ + [X] isDigit()
+ + [X] isGraph()
+ + [X] isHexadecimalDigit()
+ + [X] isLowerCase()
+ + [X] isPrintable()
+ + [X] isPunct()
+ + [X] isSpace()
+ + [X] isUpperCase()
+ + [X] isWhitespace()
+- [X] Random Numbers
+ + [X] random()
+ + [X] randomSeed()
+- [X] Bits and Bytes
+ + [X] bit()
+ + [X] bitClear()
+ + [X] bitRead()
+ + [X] bitSet()
+ + [X] bitWrite()
+ + [X] highByte()
+ + [X] lowByte()
+- [X] External Interrupts
+ + [X] attachInterrupt()
+ + [X] detachInterrupt()
+- [ ] Interrupts
+ + [ ] interrupts()
+ + [ ] noInterrupts()
+- [-] Serial
+ + [X] available()
+ + [X] availableForWrite()
+ + [X] begin()
+ + [X] end()
+ + [ ] find()
+ + [ ] findUntil()
+ + [X] flush()
+ + [ ] parseFloat()
+ + [ ] parseInt()
+ + [X] peek()
+ + [X] print()
+ + [X] println()
+ + [X] read()
+ + [X] readBytes()
+ + [ ] readBytesUntil()
+ + [ ] readString()
+ + [ ] readStringUntil()
+ + [X] setTimeout()
+ + [ ] write()
+ + [ ] serialEvent()
+- [ ] String Object
+PROGMEM, USB and Stream aren't implemented and likely never will be
+** Other functions
+change voltage of pin
+#+BEGIN_SRC C++
+an_set_voltage(pin, voltage)
+#+END_SRC
+
+Change voltage of pin from console imput
+#+BEGIN_SRC C++
+an_request_voltage(pin)
+#+END_SRC
+
+take input from console and put it in Serial buffer
+#+BEGIN_SRC C++
+Serial.an_take_input()
+#+END_SRC
+* More Examples
+** Serial and AnalogRead:
+#+BEGIN_SRC C++
+#define AN_BOARD_NANO
+#define AN_IMPL
+#include "ArduinoNative.hpp"
+
+int analogpin = A7;
+
+void setup()
+{
+ Serial.begin(9600);
+ pinMode(analogpin, INPUT);
+}
+
+void loop()
+{
+#ifdef ArduinoNative
+ an_request_voltage(analogpin);
+#endif
+ Serial.println(analogRead(analogpin));
+ delay(30);
+}
+#+END_SRC
+Output:
+#+BEGIN_SRC
+set voltage of pin 21 to: 3.0
+614
+#+END_SRC
+** Serial Read
+#+BEGIN_SRC C++
+#define AN_IMPL
+#include "ArduinoNative.hpp"
+
+void setup()
+{
+ Serial.begin(9600);
+#ifdef ArduinoNative
+ Serial.an_take_input();
+#endif
+}
+
+void loop()
+{
+ while(Serial.available()) {
+ Serial.println((char)Serial.read());
+ }
+}
+#+END_SRC
+Output:
+#+BEGIN_SRC
+ArduinoNative is requesting Serial input: hello
+h
+e
+l
+l
+o
+#+END_SRC
diff --git a/test.cpp b/test.cpp
@@ -0,0 +1,17 @@
+#define AN_IMPL
+#include "ArduinoNative.hpp"
+
+void setup()
+{
+ Serial.begin(9600);
+#ifdef ArduinoNative
+ Serial.an_take_input();
+#endif
+}
+
+void loop()
+{
+ while(Serial.available()) {
+ Serial.println((char)Serial.read());
+ }
+}