Skip to content

Instantly share code, notes, and snippets.

/SIMPL13 Secret

Created June 2, 2013 10:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/facc9a262c0778aec7b6 to your computer and use it in GitHub Desktop.
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
// 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