-
-
Save anonymous/facc9a262c0778aec7b6 to your computer and use it in GitHub Desktop.
Here' the latest version of SIMPL - with a few commands added to make I/O to LEDs a bit easier
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SIMPL 13 | |
// A Serial Interpreted Minimal Programming Language for Arduino and clones | |
// Inspired by Txtzyme - by Ward Cunningham | |
// SIMPL allows you to quickly write test programs for Arduino Input and OUtput | |
// It's great for animated LED sequences and generating audio tones | |
// SIMPL tries to take you back to an age of computing when things were simple | |
// So it compiles in under 7K - leaving lots of room for other stuff | |
// SIMPL allows new words to be defined by preceding them with colon : (Like Forth) | |
// New words use CAPITALS - so 26 words are possible in the vocabulary | |
// Words A-F have been predefined as musical tones - but you can write over them | |
// A word can be a maximum of 48 characters long | |
// Type ? to get a list off all defined words | |
// Version 13 includes new commands a, b, c, h, l and n - to make I/O easier | |
// a - sends an analog.Write value to a pin previously named with d | |
// b - prints out the current value of the milliseconds counter, allowing loop timing to be calculated | |
// c - prints out the current value of the microseconds counter | |
// h - sets a digital pin high eg 6h | |
// l - sets a digital pin low eg 13l | |
// n - decodes a number up to 4095 and displays it on digital pins 2 to 13 eg 1234n | |
// n alllows you to display any number on the LED array, to examine RAM or display data from an ADC channel | |
// 255!1000{y@rn100m} - this will display all the bytes from RAM address 256 to 1256 sequentially on the LEDS | |
// These upper case commands play some musical tones out of Digital Pin 6 | |
// 40{1o1106u0o1106u} // A 440 Hz | |
// 45{1o986u0o986u} // B 493.88 Hz | |
// 51{1o929u0o929u} // C 523.25 Hz | |
// 57{1o825u0o825u} // D 587.33 Hz | |
// 64{1o733u0o733u} // E 659.26 Hz | |
// 72{1o690u0o691u} // F 698.46 Hz | |
// 81{1o613u0o613u} // G 783.99 HZ | |
#define bufRead(addr) (*(unsigned char *)(addr)) | |
#define bufWrite(addr, b) (*(unsigned char *)(addr) = (b)) | |
unsigned char bite; | |
unsigned int x = 0; | |
unsigned int y = 0; | |
int len = 48; | |
char array[26][48] = { // Define a 26 x 48 array for the colon definitions | |
{"6d40{1o1106u0o1106u}"}, | |
{"6d45{1o986u0o986u}"}, | |
{"6d51{1o929u0o929u}"}, | |
{"6d57{1o825u0o825u}"}, | |
{"6d64{1o733u0o733u}"}, | |
{"6d72{1o690u0o691u}"}, | |
{"6d81{1o613u0o613u}"}, | |
{"_Hello World, and welcome to SIMPL_"}, | |
{"5{ABC}"}, | |
{""}, | |
{""}, | |
{""}, | |
{"_This is a test message - about 48 characters_}, | |
{"5d1o6d1o0!6{l@pd0o1000m1o}"}, | |
{"l@r"}, | |
{"l@p"}, | |
}; | |
int a = 0; // integer variables a,b,c,d | |
int b = 0; | |
int c = 0; | |
int d = 5; // d is used to denote the digital port pin for I/O operations | |
int z = 0; | |
char name; | |
char* parray; | |
char buf[64]; | |
char* addr; | |
void setup() | |
{ | |
Serial.begin(115200); | |
pinMode(2,OUTPUT); | |
pinMode(3,OUTPUT); | |
pinMode(4,OUTPUT); | |
pinMode(5,OUTPUT); | |
pinMode(6,OUTPUT); | |
pinMode(7,OUTPUT); | |
pinMode(8,OUTPUT); | |
pinMode(9,OUTPUT); | |
pinMode(10,OUTPUT); | |
pinMode(11,OUTPUT); | |
pinMode(12,OUTPUT); | |
pinMode(13,OUTPUT); | |
delay(2000); | |
Serial.println("Type H for Welcome or ? for Help"); | |
parray = &array[0][0]; // parray is the pointer to the first element | |
} | |
void loop() | |
{ | |
txtRead(buf, 64); | |
txtChk(buf); // check if it is a colon definition | |
txtEval(buf); | |
} | |
void txtRead (char *p, byte n) { | |
byte i = 0; | |
while (i < (n-1)) { | |
while (!Serial.available()); | |
char ch = Serial.read(); | |
if (ch == '\r' || ch == '\n') break; | |
if (ch >= ' ' && ch <= '~') { | |
*p++ = ch; | |
i++; | |
} | |
} | |
*p = 0; | |
} | |
void txtChk (char *buf) { // Check if the text starts with a colon and if so store in temp[] | |
if (*buf == ':') { | |
char ch; | |
int i =0; | |
while ((ch = *buf++)){ | |
if (ch == ':') { | |
Serial.println(*buf); // get the name from the first character | |
name = *buf ; | |
buf++; | |
} | |
bufWrite((parray + (len*(name-65) +i)),*buf); | |
i++; | |
} | |
x = 1; | |
} | |
} | |
void txtEval (char *buf) { | |
unsigned int k = 0; | |
char *loop; | |
char ch; | |
while ((ch = *buf++)) { | |
switch (ch) { | |
case '0': | |
case '1': | |
case '2': | |
case '3': | |
case '4': | |
case '5': | |
case '6': | |
case '7': | |
case '8': | |
case '9': | |
x = ch - '0'; | |
while (*buf >= '0' && *buf <= '9') { | |
x = x*10 + (*buf++ - '0'); | |
} | |
break; | |
case 'p': | |
Serial.println(x); | |
break; | |
case 'a': | |
analogWrite(d,x); | |
break; | |
case 'b': | |
Serial.println(millis()); | |
break; | |
case 'c': | |
Serial.println(micros()); | |
break; | |
case 'd': | |
d = x; | |
break; | |
case 'n': // Output an 12 bit value on I/O Dig 2 - Dig 13 | |
if(x>=2048){digitalWrite(13,HIGH); x = x- 2048;} else {digitalWrite(13,LOW);} | |
if(x>=1024){digitalWrite(12,HIGH); x = x- 1024;} else {digitalWrite(12,LOW);} | |
if(x>=512){digitalWrite(11,HIGH); x = x- 512;} else {digitalWrite(11,LOW);} | |
if(x>=256){digitalWrite(10,HIGH); x = x- 256;} else {digitalWrite(10,LOW);} | |
if(x>=128){digitalWrite(9,HIGH); x = x- 128;} else {digitalWrite(9,LOW);} | |
if(x>=64){digitalWrite(8,HIGH); x = x- 64;} else {digitalWrite(8,LOW);} | |
if(x>=32){digitalWrite(7,HIGH); x = x- 32;} else {digitalWrite(7,LOW);} | |
if(x>=16){digitalWrite(6,HIGH); x = x- 16;} else {digitalWrite(6,LOW);} | |
if(x>=8){digitalWrite(5,HIGH); x = x- 8;} else {digitalWrite(5,LOW);} | |
if(x>=4){digitalWrite(4,HIGH); x = x- 4;} else {digitalWrite(4,LOW);} | |
if(x>=2){digitalWrite(3,HIGH); x = x- 2;} else {digitalWrite(3,LOW);} | |
if(x>=1){digitalWrite(2,HIGH); x = x- 1;} else {digitalWrite(2,LOW);} | |
break; | |
case 'A': // Point the interpreter to the array containing the words | |
case 'B': | |
case 'C': | |
case 'D': | |
case 'E': | |
case 'F': | |
case 'G': | |
case 'H': | |
case 'I': | |
case 'J': | |
case 'K': | |
case 'L': | |
case 'M': | |
case 'N': | |
case 'O': | |
case 'P': | |
case 'Q': | |
case 'R': | |
case 'S': | |
case 'T': | |
case 'U': | |
case 'V': | |
case 'W': | |
case 'X': | |
case 'Y': | |
case 'Z': | |
name = ch - 65; | |
addr = parray + (len*name); | |
txtEval(addr); | |
break; | |
case '!': // store | |
y = x; | |
break; | |
case '@': | |
x = y; | |
break; | |
case '+': | |
x = x+y; | |
break; | |
case '-': | |
x = x-y; | |
break; | |
case '*': | |
x = x*y; | |
break; | |
case '/': | |
x = x/y; | |
break; | |
case '<': | |
if(x<y){x=1;} // If x<y x= 1 - can be combined with jump j | |
else x=0; | |
break; | |
case '>': | |
if(x>y){x=1;} // If x>y x= 1 - can be combined with jump j | |
else x=0; | |
break; | |
case 'j': // test if x = 1 and jump next instruction | |
if(x==1){*buf++;} | |
break; | |
case 'r': // read a byte from RAM | |
bite = bufRead(x); // x = address | |
x = bite; | |
Serial.write(x); // print the character | |
break; | |
case 'q': // read a block of x bytes of RAM at address y | |
for (int i=0; i<x; i++) { | |
bite = bufRead(y+i); // read the array | |
Serial.write(bite); // print the character to the serial port | |
} | |
break; | |
case 'w': // write a byte to RAM address in y, data in x | |
bufWrite(y,x); | |
break; | |
case '?': // Print out all the RAM | |
parray = &array[0][0]; // reset parray to the pointer to the first element | |
for (int j = 0; j<26; j++) { | |
Serial.write(j+65); // print the caps word name | |
Serial.write(20); // space | |
for (int i=0; i<len; i++) { | |
bite = bufRead( parray + (j *len )+i); // read the array | |
Serial.write(bite); // print the character to the serial port | |
} | |
Serial.println(); | |
} | |
for(int i = 0; i <11; i++) { | |
Serial.println(); | |
} | |
break; | |
case 't': // make millisecond count available as elapsed seconds | |
x=millis()/1000; | |
break; | |
case 'i': | |
x = digitalRead(d); | |
break; | |
case 'o': | |
digitalWrite(d, x%2); | |
break; | |
case 'm': | |
delay(x); | |
break; | |
case 'u': | |
delayMicroseconds(x); | |
break; | |
case '{': | |
k = x; | |
loop = buf; | |
while ((ch = *buf++) && ch != '}') { | |
} | |
case '}': | |
if (k) { | |
k--; | |
buf = loop; | |
} | |
break; | |
case 'k': | |
x = k; | |
break; | |
case '_': | |
while ((ch = *buf++) && ch != '_') { | |
Serial.print(ch); | |
} | |
Serial.println(); | |
break; | |
case 's': | |
x = analogRead(x); | |
break; | |
case 'y': | |
y = y+1; | |
break; | |
case 'x': | |
x = x + 1; | |
break; | |
case 'h': // set bit high | |
digitalWrite(x, HIGH); | |
break; | |
case 'l': // set bit low | |
digitalWrite(x, LOW);; | |
break; | |
} | |
} | |
// Serial.println(" OK"); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment