All Projects → mikaelpatel → Arduino-Shell

mikaelpatel / Arduino-Shell

Licence: other
RPN Postscript/Forth Command Shell for Arduino

Programming Languages

C++
36643 projects - #6 most used programming language

Projects that are alternatives of or similar to Arduino-Shell

Arduino-FVM
Byte Token Threaded Forth Virtual Machine (FVM) for Arduino
Stars: ✭ 35 (+84.21%)
Mutual labels:  virtual-machine, arduino-library
library-registry
Arduino Library Manager list
Stars: ✭ 95 (+400%)
Mutual labels:  arduino-library
SBTCVM-Gen2-9
SBTCVM is a virtual machine implementation of a balanced ternary (base 3) computer. Features several compiled languages for ternary software development.
Stars: ✭ 32 (+68.42%)
Mutual labels:  virtual-machine
SerialTransfer
Arduino library to transfer dynamic, packetized data fast and reliably via Serial, I2C, or SPI
Stars: ✭ 273 (+1336.84%)
Mutual labels:  arduino-library
TLE5012-Magnetic-Angle-Sensor
This repository includes an library for Arduino for the TLE5012 Magnetic Angle Sensor with SSC interface.
Stars: ✭ 37 (+94.74%)
Mutual labels:  arduino-library
PMserial
Arduino library for PM sensors with serial interface
Stars: ✭ 41 (+115.79%)
Mutual labels:  arduino-library
butterfly
Butterfly connects Virtual Machines and control their traffic flow
Stars: ✭ 48 (+152.63%)
Mutual labels:  virtual-machine
DCCpp
This is the library version of DCC++ for Arduino, to control railroading DCC devices.
Stars: ✭ 18 (-5.26%)
Mutual labels:  arduino-library
arduino-cereal
Drop-in replacement for Arduino's serial monitor with variable watches.
Stars: ✭ 45 (+136.84%)
Mutual labels:  arduino-library
qp-arduino
QP real-time embedded frameworks/RTOS for Arduino (AVR and SAM)
Stars: ✭ 37 (+94.74%)
Mutual labels:  arduino-library
Adafruit CCS811
Arduino driver for CCS811 digital gas sensor
Stars: ✭ 60 (+215.79%)
Mutual labels:  arduino-library
SparkFun CCS811 Arduino Library
A library to drive the AMS CCS811 air quality sensor
Stars: ✭ 38 (+100%)
Mutual labels:  arduino-library
SparkFun SerLCD Arduino Library
A library to seamlessly control the SparkFun SerLCD over I2C, SPI, and Serial.
Stars: ✭ 18 (-5.26%)
Mutual labels:  arduino-library
ESP32BleAdvertise
Simple library for BLE advertise using ESP32 in Arduino
Stars: ✭ 39 (+105.26%)
Mutual labels:  arduino-library
thislang
A subset of javascript implemented in that subset of javascript. Yes, it can run itself.
Stars: ✭ 31 (+63.16%)
Mutual labels:  virtual-machine
misp-packer
Build Automated Machine Images for MISP
Stars: ✭ 25 (+31.58%)
Mutual labels:  virtual-machine
Queue
Queue handling library (designed on Arduino)
Stars: ✭ 73 (+284.21%)
Mutual labels:  arduino-library
wavm
Wait, another virtual machine ?
Stars: ✭ 61 (+221.05%)
Mutual labels:  virtual-machine
vm
The mm-ADT Virtual Machine
Stars: ✭ 29 (+52.63%)
Mutual labels:  virtual-machine
ServoTimer2
ServoTimer2 is a simple library for Arduino 1.x that does not use Timer1 in case of a conflict.
Stars: ✭ 29 (+52.63%)
Mutual labels:  arduino-library

Arduino-Shell

This library provides a Forth/PostScript style shell for Arduino sketches. Shell is a virtual stack machine with a byte token threaded instruction set. The tokens, characters, are chosen so that it is possible to write small scripts directly without a token compiler. As Forth scripts are written in Reverse Polish Notation (RPN), and executed in the given order.

screenshot

Shell has built-in instruction level trace to aid script debugging and performance tuning. It prints the instruction cycle count, script address, opcode (or full operation name), stack depth and contents. Typical output in the Serial Monitor above.

Shell can be configured to trace full operation names or tokens.

The classical Arduino Blink sketch in the shell script language is

 13O{13H1000D13L1000DT}w

And with some extra spacing to make the operations easier to read.

 13 O { 13 H 1000 D 13 L 1000 D T } w

And with full instruction names and some formatting:

 13 output
 {
   13 high 1000 delay
   13 low  1000 delay
   true
 } while

A further compressed version (shorter):

 13 output
 {
   1000 13 over over high delay
   low delay
   true
 } while

 13O{1000,13ooHDLDT}w

And a slightly faster version:

 1000 13 dup output
 {
   over over high delay
   over over low delay
   true
 } while

 1000,13uO{ooHDooLDT}w

And an even shorter version:

 13 output
 {
   13 digitalToggle 1000 delay
   true
 } while

13O{13X1000DT}w

Scripts can be defined and executed from both Random Access Memory (SRAM), Electrically Erasable Programmable Read-Only Memory (EEPROM), and Program Memory (PROGMEM). The supporting data type script_t and macro SCRIPT can be used to define an application dictionary with program memory based scripts. All named scripts are persistent. Variables may be written to EEPROM with the operation z. They are automatically restored at startup together with defined scripts.

Install

Download and unzip the Arduino-Shell library into your sketchbook libraries directory. Rename from Arduino-Shell-master to Arduino-Shell.

The Shell library and examples should be found in the Arduino IDE File>Examples menu.

Instruction Set

Opcode Parameters Description Forth
, -- no operation
+ x y -- x+y addition +
- x y -- x-y subtraction -
* x y -- x*y multiplication *
/ x y -- x/y division /
% x y -- x%y modulo MOD
# x y -- x!=y not equal
= x y -- x==y equal =
< x y -- x<y less than <
> x y -- x>y greater than >
~ x -- ~x bitwise not NOT
& x y -- x&y bitwise and AND
| x y -- x|y bitwise or OR
^ x y -- x^y bitwise xor XOR
@ addr -- val read variable @
! val addr -- write variable !
. x -- print number followed by one space .
? addr -- print variable ?
; addr block -- copy block and assign variable (function)
\ x1..xn n -- x1..xn n > 0: mark stack frame with n-elements
\ x1..xn y1..ym n -- y1..ym n < 0: remove stack frame with n-elements
$ n -- addr address of n-element in frame
a -- bytes entries allocated eeprom
b base -- number print base BASE
c xn..x1 n -- drop n stack elements
d x -- drop DROP
e flag if-block else-block -- execute block on flag IF ELSE THEN
f addr -- forget variable
g xn..x1 n -- xn-1..x1 xn rotate n-elements ROLL
h x y z -- (x*y)/z scale */
i flag block -- execute block if flag is true IF THEN
j xn..x1 -- xn..x1 n stack depth DEPTH
k -- char read character from input stream KEY
l low high block( index -- ) -- execute block from low to high DO LOOP
m -- write new line to output stream CR
n x -- -x negate NEGATE
o x y -- x y x over OVER
p xn..x1 n -- xn..x1 xn pick PICK
q x -- [x x] or 0 duplicate if not zero ?DUP
r x y z --- y z x rotate ROT
s x y -- y x swap SWAP
t addr -- bool write variable name to output stream .NAME
u x -- x x duplicate DUP
v char -- write character to output stream EMIT
w block( -- flag) -- execute block while flag is true BEGIN UNTIL
x block -- execute block EXECUTE
y -- yield for multi-tasking scheduler
z addr -- write variable to eeprom memory
A pin -- sample analogRead(pin)
C xn..x1 -- clear ABORT
D ms -- delay
E period addr -- bool check if timer variable has expired
F -- false false FALSE
H pin -- digitalWrite(pin, HIGH)
I pin -- pinMode(pin, INPUT)
K -- [char true] or false non-blocking read character from input stream ?KEY
L pin -- digitalWrite(pin, LOW)
M -- ms millis()
N -- no operation
O pin -- pinMode(pin, OUTPUT)
P value pin -- analogWrite(pin, value)
R pin -- bool digitalRead(pin)
S -- print stack contents .S
T -- true true TRUE
U pin -- pinMode(pin, INPUT_PULLUP)
W value pin -- digitalWrite(pin, value)
X pin -- digitalToggle(pin)
Y -- list dictionaries WORDS
Z -- toggle trace mode

Special forms

The shell script language allows several special forms such as literal values, blocks, control structures and argument frames.

Boolean

Boolean values are true(-1) and false(0). Mapping to boolean may be done with testing non-zero (0#). Defining true(-1) allows Boolean values and relation operations to be directly combined with bitwise operations.

 10 0 # . m
 T F ~ = . m

The instructions to push the boolean values are T and F.

Literal Numbers

Integer numbers (decimal, binary and hexadecimal) may be used directly in scripts. When the script is executed the value of the number is pushed on the parameter stack. The statement:

 println((3 + (-5)) * 6);

may be written as the following script expression:

 3 -5 + 6 * . m

and compressed to:

 3,-5+6*.m

Binary literal numbers are prefixed with 0b, and hexadecimal with 0x as in C.

 10 . 0b10 . 0x10 .

Literal Characters

Quote (apostrophe) a character to push it on the parameter stack.

 'A .

Variables

Variables are defined with :name. The operator will push the address of the variable on the parameter stack. It may be accessed using the operators fetch @ and store !.

 42:x!
 :x@

The operator ? can be used to print the value of a variable.

 :x?

It is short hand for:

 :x@.

Blocks

Code blocks have the following form { code-block }. When the script is executed the address of the block is pushed on the parameter stack. The block can be executed with the instruction x.

 { code-block } x

The operation ; will copy a block to the eeprom and assign a variable. Used in the form:

 :fun { code-block };
 :fun@x

The short hand for executing a function is `name.

 `fun

The instruction f may be used to forget variable(s). The eeprom allocation point is reset accordingly.

 :fun,f

Control Structures

Control structures follow the same format at PostScript. They are also in Reverse Polish Notation (RPN). The blocks are pushed on the parameter stack before the control structure instruction. Below are the control structures with full instruction names.

 bool { if-block } if
 bool { if-block } { else-block } ifelse

 low high { index loop-block } loop

 { while-block bool } while

The loop-block will recieve the current index on top of parameter stack. The while-block should push a non-zero value to continue the while loop otherwise zero (false) to terminate the loop.

The instructions are i for if, e for ifelse, l for loop and w for while.

Output Strings

Output strings have the following form ( output-string ). When executed the string within the parenthesis is written to the output stream. The instruction m will print a new-line (corresponds to forth cr).

Stack Marker

A stack marker has the following form [ code-block ]. When executed the number of stack elements generated by the code block is pushed on the parameter stack.

Frame Marker

A frame marker has the following form n\ ... -n\ where n is the number of elements (parameters and locals) in the frame. Positive n marks the frame and negative n removes the frame stack elements leaving any return values. Elements within the frame can be accessed with m$ where m is the element index (1..n). The element address is pushed on the parameter stack and the value may be accessed with fetch @ and store !.

Swap could be defined as:

 :swap {2\2$@1$@-2\};

which will mark a frame with two arguments, copy the second and then the first argument, and last remove the frame, leaving the two return values.

Extended Instructions

Shell allows application extension with a virtual member function, trap(). The function is called when the current instruction could not be handled. The trap() function may parse any number of instructions. Underscore _ is used as the escape operation code.

Example Scripts

Blink

Turn board LED, pin 13, on/off with 1000 ms period.

 13 output
 {
   13 high 1000 delay
   13 low 1000 delay
   true
 } while

Script:

 13O{13H1000D13L1000DT}w

Blink with digitalToggle

Toggle board LED, pin 13, on/off with 1000 ms period.

 13 output
 {
   13 digitalToggle 1000 delay
   true
 } while

Script:

 13O{13X1000DT}w

Blink without delay

Turn board LED, pin 13, on/off without using delay. Use timer expired instruction.

 13 output
 {
   1000 `timer ?expired
   { 13 digitalToggle } if
   true
 } while

Script:

 13O{1000:timer,E{13X}iT}w

Blink controlled by on/off button

Turn board LED, pin 13, on/off with 1000 ms period if pin 2 is low.

 2 inputPullup
 13 output
 {
   2 digitalRead not
   {
     13 high 1000 delay
     13 low 1000 delay
   } if
   true
 } while

Script:

 2U13O{2R~{13H1000D13L1000D}iT}w

Read Analog Pins

Read analog pins and print value in format "An = value".

 0 4 { ." A" dup . ." =" analogRead . cr } loop

Script:

 0,4{(A)u.(= )A.m}l

Continously Read Analog Pins

Read analog pins (0..4) and print value continuously with 100 ms delay.

 {
   0 4 { analogRead . } loop
   cr 100 delay true
 } while

Script:

 {0,4{A.}lm100DT}w

Termostat

Read analog pin 0, turn board LED on if value is within 100..200 else off.

 13 output
 {
   0 analogRead
   dup 100 < swap 200 > or not
   13 digitalWrite
   true
 } while

Script:

 13O{0Au100<s200>|~13WT}w

Range check function

Check that a given parameter is within a range low to high.

 : within ( x low high -- bool )
   rot swap over swap > swap rot < or not ;

  10 5 100 within .
 -10 5 100 within .
 110 5 100 within .

Script:

 :within{rsos>sr<|~};
  10,5,100`within.
 -10,5,100`within.
 110,5,100`within.

Range check function with stack frame

Check that a given parameter is within a range low to high. Use a stack frame for the three parameters.

 : within { x low high -- bool }
   x @ high @ > x @ low @ < or not ;

  10 5 100 within .
 -10 5 100 within .
 110 5 100 within .

Script:

 :within{3\1$@3$@>1$@2$@<|~-3\};
  10,5,100`within.
 -10,5,100`within.
 110,5,100`within.

Iterative Factorial (while)

Calculate factorial number of given parameter.

 : fac ( n -- n! )
   1 swap
   {
     dup 0>
       { swap over * swap 1- true }
       { drop false }
     ifelse
   } while ;

 5 fac .

Script:

 :fac{1s{u0>{so*s1-T}{dF}e}w};
 5`fac.

Iterative Factorial (loop)

Calculate factorial number of given parameter.

 : fac ( n -- n! | n > 0 )
   1 2 rot { * } loop ;

 5 fac .

Script:

 :fac{1,2r{*}l};
 5`fac.

Recursive Factorial

Calculate factorial number of given parameter.

 : fac ( n -- n! )
   dup 0>
     { dup 1- fac * }
     { drop 1 }
   ifelse ;

 5 fac .

Script:

 :fac{u0>{u1-`fac*}{d1}e};
 5`fac.

Stack vector sum

Sum a vector of integers on stack. Use that stack marker to get number of elements in vector.

 [ 1 2 3 4 5 6 7 8 ] 0 1 rot { drop + } loop

Script:

 [1,2,3,4,5,6,7,8]0,1r{d+}l
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].