Skip to content

Latest commit

 

History

History
1007 lines (809 loc) · 24.3 KB

arduino.org

File metadata and controls

1007 lines (809 loc) · 24.3 KB

emacs-lisp functions

(defun my-send (beg end)
  (interactive "r")
  (process-send-region "/dev/ttyUSB0" beg end))
(global-set-key (kbd "M-p") 'my-send)

serial port setup

Current baud rate115200

Python function definitions

def read_file_to_string(fname):
    """
    Reads file to a string
    :param fname: string
    :returns: string
    """
    with open(fname, "r") as file1:
        read_content = file1.read()
    return read_content

def write_string_to_file(fname,string):    
    with open(fname, "w") as file1:
        file1.write(string)

def dict_from_columns(ind1,ind2,table):
    fnames = {}
    for i in table:
        var=i[ind1]
        value=i[ind2]
        fnames[var]=value
    return fnames

def quote_lisp_library_text(mystring):
    lines = mystring.splitlines()
    fline2 = ""
    for line in lines:
        if line=="": continue
        fline1 = line.replace('"','\\"')
        fline = '\"' + fline1 + '\"'
        fline2 = fline2 + fline + "\n"
    return fline2[0:-1] + ";\n"

Help functions

(defun sq (x) (* x x))
(defun cub (x) (* x x x))

GPS

(defun parse-gps (gps-string)
  (let ((parts (split gps-string ",")))
    (cond
      ((= (length parts) 15)
       (let ((lat (parse-coord (nth 2 parts)))
             (lat-dir (nth 3 parts))
             (lon (parse-coord (nth 4 parts)))
             (lon-dir (nth 5 parts)))
         (list lat lat-dir lon lon-dir)))
      (t nil))))

(defun parse-coord (coord)
  (let ((degrees (floor (float (nth 0 coord))))
        (minutes (float (nth 1 coord)))
        (seconds (float (nth 2 coord))))
    (+ (* degrees 100) (/ minutes 60) (/ seconds 3600))))

(print (parse-gps "$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47"))
  (with-serial (str 3 96)(loop(print (read-line str))))
(+ 1 1)

example ino code for connecting to gps

#include <SoftwareSerial.h>

// Choose two Arduino pins to use for software serial
int RXPin = 16;
int TXPin = 17;

//Default baud of NEO-6M is 9600
int GPSBaud = 9600;

// Create a software serial port called "gpsSerial"
SoftwareSerial gpsSerial(RXPin, TXPin);

void setup()
{
  // Start the Arduino hardware serial port at 9600 baud
  Serial.begin(115200);

  // Start the software serial port at the GPS's default baud
  gpsSerial.begin(GPSBaud);
}

void loop()
{
  // Displays information when new sentence is available.
  while (gpsSerial.available() > 0)
    Serial.write(gpsSerial.read());
}

function names

	{ bmpt, (fn_ptr_type)fn_isbmpconnected, 0x00, doc_isbmpconnected },
	{ printbmp, (fn_ptr_type)fn_printbmptoserial, 0x00, doc_printbmptoserial },
	{ readcompass, (fn_ptr_type)fn_readcompass, 0x00, doc_readcompass },
	{ initcompass, (fn_ptr_type)fn_initcompass, 0x00, doc_initcompass },
	{ beginserial2, (fn_ptr_type)fn_beginserial2, 0x00, doc_beginserial2 },
	{ printserial2, (fn_ptr_type)fn_printserial2, 0x00, doc_printserial2 },
//	{ initgps, (fn_ptr_type)fn_initgps, 0x00, doc_initgps },

function documentation

const char doc_isbmpconnected[] PROGMEM = "(isbmpconnected)\n"
"Checks is BMP device is connected and begins bmp.";
const char doc_printbmptoserial[] PROGMEM = "(printbmptoserial)\n"
"Prints bmp data to serial port";
const char doc_readcompass[] PROGMEM = "(readcompass)\n"
"reads compass values and return them to serial";
const char doc_initcompass[] PROGMEM = "(initcompass)\n"
"initialize compass";
const char doc_beginserial2[] PROGMEM = "(beginserial2)\n"
"begins serial2 at pins 16,17 ";
const char doc_printserial2[] PROGMEM = "(printserial2)\n"
"prints serial2 to serial";
const char bmpt[] PROGMEM = "isbmpconnected";
const char printbmp[] PROGMEM = "printbmptoserial";

const char readcompass[] PROGMEM = "readcompass";
const char initcompass[] PROGMEM = "initcompass";

const char beginserial2[] PROGMEM = "beginserial2";
const char printserial2[] PROGMEM = "printserial2";
object *fn_beginserial2 (object *args, object *env) {
  Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
  return nil;
}

object *fn_printserial2 (object *args, object *env) {
  while (Serial2.available()) {
    Serial.print(char(Serial2.read()));
  }
  return nil;
}

Serial port

#define RXD2 16
#define TXD2 17

void setup() {
  // Note the format for setting a serial port is as follows: Serial2.begin(baud-rate, protocol, RX pin, TX pin);
  Serial.begin(115200);
  //Serial1.begin(9600, SERIAL_8N1, RXD2, TXD2);
  Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
  Serial.println("Serial Txd is on pin: "+String(TX));
  Serial.println("Serial Rxd is on pin: "+String(RX));
}

void loop() { //Choose Serial1 or Serial2 as required
  while (Serial2.available()) {
    Serial.print(char(Serial2.read()));
  }
}

DS3221

(defun ds3231-set (hr min)
  (with-i2c (str #x68)
    (write-byte 0 str)
    (write-byte 0 str)
    (write-byte min str)
    (write-byte hr str)))

(defun ds3231-time ()
  (with-i2c (str #x68)
    (write-byte 0 str)
    (restart-i2c str 3)
    (list
     (read-byte str)
     (read-byte str)
     (read-byte str))))

(defun ds3231_printtime ()
  (with-i2c (str #x68)
    (write-byte 0 str)
    (restart-i2c str 3)
    (let ((time (list (read-byte str) (read-byte str) (read-byte str))))
      (format t "~2x:~2x:~2x" (nth 2 time) (nth 1 time) (nth 0 time)))))

(defun ds3231_printregisterb (addr)
  (with-i2c (str #x68)
	    (write-byte addr str)
	    (restart-i2c str 1)
	    (format t "~b~%" (read-byte str))))


(defun ds3231_printregisterh (addr)
  (with-i2c (str #x68)
	    (write-byte addr str)
	    (restart-i2c str 1)
	    (format t "~x~%" (read-byte str))))

(defun ds3231_printregisterd (addr)
  (with-i2c (str #x68)
	    (write-byte addr str)
	    (restart-i2c str 1)
	    (format t "~d~%" (read-byte str))))

SD card

updatedesp32-17.11.2022
sdcard-esp32
3v33.3v
csgpio5
mosigpio23
clkgpio18
misogpio19
gndgnd
(defun test_sdcard ()
  (print "Write program")
  (with-sd-card (s "lisp.txt" 2)
    (write-string "(defun sq (x) (* x x))" s))
  (print "Load program")
  (with-sd-card (s "lisp.txt")
    (eval (read s)))
  (print (sq 123)))

https://github.com/keepworking/Mecha_QMC5883L.git

https://github.com/technoblogy/ulisp-esp.git

https://github.com/kurimawxx00/esp32-magnetometer-hmc5883l.git

Compass

(dotimes (p 20) (readcompass))

MPU-6050

Deviceaddress decimaladdress hex
MPU6050 I2C Address1040x68
reset address1070x6Bset 0
read accelaration (ACCEL_XOUT_H)590x3B6 bytes (XYZ_16bit_MSB/LSB)
ACCEL_CONFIG register280x1Cchange scale
set +/- 8g160x10
(reset_MPU6050)
(MPU6050_readscale)
(MPU6050_readtemp)
(read_MPU6050)
(defun reset_MPU6050 ()
  (with-i2c (str #x69) 
    (write-byte #x6B str)
    (write-byte #x0 str)))

(defun MPU6050_readscale ()
  (with-i2c (str #x69) 
	    (write-byte #x1C str)
	    (restart-i2c str 1) 
	    (read-byte str)))

(defun MPU6050_readtemp ()
  "it is ok if temperature>36.5"
  (defvar tempout1 0)
  (defvar tempout2 0)
  (with-i2c (str #x69) 
	    (write-byte #x41 str)
	    (restart-i2c str 1) 
	    (setf tempout1 (read-byte str))
	    (write-byte #x42 str)
	    (restart-i2c str 1) 
	    (setf tempout2 (read-byte str))
	    )
  (format t "~x,~x~%" tempout1 tempout2))

(defun ct (tempout1 tempout2)
  (let ((temp 0))
    (if (= 1 (ash tempout1 -7))
	(setf temp (+ (/ tempout2 340.0) (* (- tempout1 256) (/ 256 340.0)) 36.53))
        (setf temp (+ (/ (logior (ash tempout1 8) tempout2) 340.0 ) 36.53) ))
    (format t "MPU_temp:~d~%" temp)
    ))
	
(defun checktemp (i j)
  (dotimes (p i) (delay j)
	   (MPU6050_readtemp)
	   (ct tempout1 tempout2)
	   (printbmptoserial)))

(defun MPU6050_setscale8g ()
  (with-i2c (str #x69) 
    (write-byte #x1C str)
    (write-byte #x10 str)))

(defun MPU6050_setscale2g ()
  (with-i2c (str #x69) 
    (write-byte #x1C str)
    (write-byte #x00 str)))

(defun read_MPU6050 ()
  (with-i2c (str #x69) 
    (write-byte #x3B str)
    (restart-i2c str 6) 
    (list (read-byte str) (read-byte str) (read-byte str) (read-byte str) (read-byte str) (read-byte str))))

(defun scan_MPU6050_long (i k) 
  (dotimes (p i)
    (delay k)
    (with-i2c (str #x69) 
      (write-byte #x3B str)
      )
    (let* ((r (read_MPU6050))
	   (x0 (nth 0 r))(x1 (nth 1 r))
	   (y0 (nth 2 r))(y1 (nth 3 r))
	   (z0 (nth 4 r))(z1 (nth 5 r)))
      (format t "~3d:: X:~3d:~3d  Y:~3d:~3d  Z:~3d:~3d~%" p x0 x1 y0 y1 z0 z1))))

(defun scan_MPU6050 () (format nil "~{ ~d ~}" (read_MPU6050)))

GY-271

(with-i2c (str #x68) (write-byte 0 str) (write-byte 1 str) (write-byte 2 str))

(with-i2c (str 0x0D) (write-byte 0x0B str) (write-byte 0x01 str) (write-byte 0x09 str) (write-byte 0x1D str) )

(with-i2c (str 13) (write-byte 11 str) (write-byte 1 str) (write-byte 9 str) (write-byte 29 str) )

(with-i2c (str 13) (write-byte 0 str) )

(defvar i 100)
(defun mag (i)
(if (< i 1) 0
(progn
(setf i (- i 1))
(prin1 (get_magneto))
(format t "~%")
(mag i)
))))
(defun get_magneto ()
  (with-i2c (str 13) 
	    (write-byte 0 str)
	    (restart-i2c str 6)
	    (list
	     (read-byte str)
	     (read-byte str)
	     (read-byte str)
	     (read-byte str)
	     (read-byte str)
	     (read-byte str))))
(format t i)
(concat
(format "Compass|0x0D:|%d\n" #x0D)(format "||0x0B:|%d|\n" #x0B)(format "||0x1D:|%d|\n" #x1D)
(format "||0x68:|%d|" #x68)
)
(concat
(format "0x0D:%d\n" #x0D)
(format "0x0B:%d\n" #x0B)
(format "0x1D:%d" #x1D)
)

(defun get () (with-i2c (str 13 3) (list (read-byte str) (read-byte str) (read-byte str))))

i2c

I2C DeviceESP32
SDASDA (default is GPIO 21)
SCLSCL (default is GPIO 22)
GNDGND
VCCusually 3.3V or 5V

scan i2c ports

(defun scan ()
  (progn
    (format t "---~%")
    (dotimes (p 127)
      (with-i2c (str p)
	(when str (progn
		    (format t "~d  - ~0x ~%" p p)
		    (delay 100))
    ))
  (delay 10)
  )
  (format t "---~%")
  ))

(scan)

how to return alist

object *fn_reverse (object *args, object *env) {
  (void) env;
  object *list = first(args);
  object *result = NULL;
  while (list != NULL) {
    if (improperp(list)) error(REVERSE, notproper, list);
    push(first(list),result);
    list = cdr(list);
  }
  return result;
}

LispLibrary

exports quoted results

  1. Tangle code here
  2. export it quoted, to add it to .ino file
(with-open-file (stream "arduino.lisp")
  (with-open-file (f "/home/me/arduino/arduino2.lib" :direction :output
						    :if-exists :supersede
						    :if-does-not-exist :create)
    (do ((line (read-line stream nil)
	       (read-line stream nil)))
	((null line))
      (print line)
      (let ((l (format nil "\"~a\"~%" line)))
	(write-sequence l f)))))

check loaded functions

(list-library)

enums

ISBMPCONNECTED, PRINTBMPTOSERIAL,
READCOMPASS, INITCOMPASS,
BEGINSERIAL2,PRINTSERIAL2,

headers

Add following code to template:

#include <SoftwareSerial.h>

#define addr 0x0D; //I2C Address for The HMC5883
#define sdcardsupport
#define lisplibrary
#define RXD2 16
#define TXD2 17

int GPSBaud = 9600;

SoftwareSerial gpsSerial(RXD2, TXD2);

C-FUNCTIONS

object *fn_initcompass (object *args, object *env) {
	int addr = 0x0D;
	//  Serial.begin(9600);
  Wire.begin();
  Wire.beginTransmission(addr); //start talking
  Wire.write(0x0B); // Tell the HMC5883 to Continuously Measure
  Wire.write(0x01); // Set the Register
  Wire.endTransmission();
  Wire.beginTransmission(addr); //start talking
  Wire.write(0x09); // Tell the HMC5883 to Continuously Measure
  Wire.write(0x1D); // Set the Register
  Wire.endTransmission();
	return nil;
}
object *fn_readcompass (object *args, object *env) {
	//	Serial.begin(9600);
	int addr = 0x0D;
  int x, y, z; //triple axis data
  //Tell the HMC what regist to begin writing data into
  Wire.beginTransmission(addr);
  Wire.write(0x00); //start with register 3.
  Wire.endTransmission();
  //Read the data.. 2 bytes for each axis.. 6 total bytes
  Wire.requestFrom(addr, 6);
  if (6 <= Wire.available()) {
    x = Wire.read(); //MSB  x
    x |= Wire.read() << 8; //LSB  x
    z = Wire.read(); //MSB  z
    z |= Wire.read() << 8; //LSB z
    y = Wire.read(); //MSB y
    y |= Wire.read() << 8; //LSB y
  }
  // Show Values
  Serial.print("X Value: ");
  Serial.println(x);
  Serial.print("Y Value: ");
  Serial.println(y);
  Serial.print("Z Value: ");
  Serial.println(z);
  Serial.println();
	//  delay(100);
	return nil;
}
object *fn_isbmpconnected (object *args, object *env) {
  //check if bmp exists
  if (!bmp.begin()) {
  Serial.println("Could not find a valid BMP085 sensor, check wiring!");
  }
  return nil;
}

object *fn_printbmptoserial (object *args, object *env) {
    Serial.print("Temperature = ");
    Serial.print(bmp.readTemperature());
    Serial.println(" *C");
    
    Serial.print("Pressure = ");
    Serial.print(bmp.readPressure());
    Serial.println(" Pa");
    
    // Calculate altitude assuming 'standard' barometric
    // pressure of 1013.25 millibar = 101325 Pascal
    Serial.print("Altitude = ");
    Serial.print(bmp.readAltitude());
    Serial.println(" meters");

    Serial.print("Pressure at sealevel (calculated) = ");
    Serial.print(bmp.readSealevelPressure());
    Serial.println(" Pa");
}

full code

// Includes #include <Adafruit_BMP085.h> Adafruit_BMP085 bmp; #define addr 0x0D //I2C Address for The HMC5883

// Insert your own function names here const char bmpt[] PROGMEM = “isbmpconnected”; const char printbmp[] PROGMEM = “printbmptoserial”; const char readcompass[] PROGMEM = “readcompass”; const char initcompass[] PROGMEM = “initcompass”;

{ bmpt, (fn_ptr_type)fn_isbmpconnected, 0x00, doc_isbmpconnected }, { printbmp, (fn_ptr_type)fn_printbmptoserial, 0x00, doc_printbmptoserial },

{ readcompass, (fn_ptr_type)fn_readcompass, 0x00, doc_readcompass }, { initcompass, (fn_ptr_type)fn_initcompass, 0x00, doc_initcompass },

// Insert your own function documentation here const char doc_readcompass[] PROGMEM = “(readcompass)\n” “reads compass values and return them to serial”; const char doc_initcompass[] PROGMEM = “(initcompass)\n” “initialize compass”;

BMP 085

#include <Adafruit_BMP085.h>
#include <SPI.h>
#include <SD.h>

File myFile;

Adafruit_BMP085 bmp;

float bmpTemp;
float bmpPressure;
float bmpAltitude;
float bmpSealevelPressure;
float bmpRealaltitude;

char buffer[40];

void setup() {
  Serial.begin(9600);

  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  
  Serial.print("Initializing SD card...");

  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");
  
  if (!bmp.begin()) {
  Serial.println("Could not find a valid BMP085 sensor, check wiring!");
  while (1) {}
  }
}

void printbmptoserial () {
    Serial.print("Temperature = ");
    Serial.print(bmp.readTemperature());
    Serial.println(" *C");
    
    Serial.print("Pressure = ");
    Serial.print(bmp.readPressure());
    Serial.println(" Pa");
    
    // Calculate altitude assuming 'standard' barometric
    // pressure of 1013.25 millibar = 101325 Pascal
    Serial.print("Altitude = ");
    Serial.print(bmp.readAltitude());
    Serial.println(" meters");

    Serial.print("Pressure at sealevel (calculated) = ");
    Serial.print(bmp.readSealevelPressure());
    Serial.println(" Pa");
}

void loop() {
  bmpTemp = bmp.readTemperature(); 
  bmpPressure = bmp.readPressure();
  bmpAltitude = bmp.readAltitude();
  bmpSealevelPressure = bmp.readSealevelPressure();
  bmpRealaltitude = bmp.readAltitude(101500);

  printbmptoserial();

  sprintf(buffer,"%f,%f,%,%f",bmpTemp,bmpPressure,bmpSealevelPressure,bmpRealaltitude);
  Serial.println(buffer);
  myFile = SD.open("test.txt", FILE_WRITE);

  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    // close the file:
    myFile.close();
  }
}
#include <Adafruit_BMP085.h>
#include <SPI.h>
#include <SD.h>

void setup() {
  Serial.begin(9600);
  if (!bmp.begin()) {
	Serial.println("Could not find a valid BMP085 sensor, check wiring!");
	while (1) {}
  }

  float bmpTemp = bmp.readTemperature(); 
  float bmpPressure = bmp.readPressure();
  float bmpAltitude = bmp.readAltitude();
  float bmpSealevelPressure = bmp.readSealevelPressure();
  float bmpRealaltitude =  bmp.readAltitude(101500);
}

void printbmptoserial () {
    Serial.print("Temperature = ");
    Serial.print(bmp.readTemperature());
    Serial.println(" *C");
    
    Serial.print("Pressure = ");
    Serial.print(bmp.readPressure());
    Serial.println(" Pa");
    
    // Calculate altitude assuming 'standard' barometric
    // pressure of 1013.25 millibar = 101325 Pascal
    Serial.print("Altitude = ");
    Serial.print(bmp.readAltitude());
    Serial.println(" meters");

    Serial.print("Pressure at sealevel (calculated) = ");
    Serial.print(bmp.readSealevelPressure());
    Serial.println(" Pa");
}

void loop() {
  bmpTemp = bmp.readTemperature(); 
  bmpPressure = bmp.readPressure();
  bmpAltitude = bmp.readAltitude();
  bmpSealevelPressure = bmp.readSealevelPressure();
  bmpRealaltitude = bmp.readAltitude(101500);
  printbmptoserial();
}
#include <Adafruit_BMP085.h>

/*************************************************** 
  This is an example for the BMP085 Barometric Pressure & Temp Sensor

  Designed specifically to work with the Adafruit BMP085 Breakout 
  ----> https://www.adafruit.com/products/391

  These pressure and temperature sensors use I2C to communicate, 2 pins
  are required to interface
  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ****************************************************/

// Connect VCC of the BMP085 sensor to 3.3V (NOT 5.0V!)
// Connect GND to Ground
// Connect SCL to i2c clock - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 5
// Connect SDA to i2c data - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 4
// EOC is not used, it signifies an end of conversion
// XCLR is a reset pin, also not used here

Adafruit_BMP085 bmp;
  
void setup() {
  Serial.begin(9600);
  if (!bmp.begin()) {
	Serial.println("Could not find a valid BMP085 sensor, check wiring!");
	while (1) {}
  }
}
  
void loop() {
    Serial.print("Temperature = ");
    Serial.print(bmp.readTemperature());
    Serial.println(" *C");
    
    Serial.print("Pressure = ");
    Serial.print(bmp.readPressure());
    Serial.println(" Pa");
    
    // Calculate altitude assuming 'standard' barometric
    // pressure of 1013.25 millibar = 101325 Pascal
    Serial.print("Altitude = ");
    Serial.print(bmp.readAltitude());
    Serial.println(" meters");

    Serial.print("Pressure at sealevel (calculated) = ");
    Serial.print(bmp.readSealevelPressure());
    Serial.println(" Pa");

  // you can get a more precise measurement of altitude
  // if you know the current sea level pressure which will
  // vary with weather and such. If it is 1015 millibars
  // that is equal to 101500 Pascals.
    Serial.print("Real altitude = ");
    Serial.print(bmp.readAltitude(101500));
    Serial.println(" meters");
    
    Serial.println();
    delay(500);
}
/*
  SD card read/write

  This example shows how to read and write data to and from an SD card file
  The circuit:
   SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4 (for MKRZero SD: SDCARD_SS_PIN)

  created   Nov 2010
  by David A. Mellis
  modified 9 Apr 2012
  by Tom Igoe

  This example code is in the public domain.

*/

#include <SPI.h>
#include <SD.h>

File myFile;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.print("Initializing SD card...");

  if (!SD.begin(4)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open("test.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }

  // re-open the file for reading:
  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");

    // read from the file until there's nothing else in it:
    while (myFile.available()) {
      Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
}

void loop() {
  // nothing happens after setup
}

code runs by table variables

S110.0
S230.0
S340.0
(setf w
(loop for i in inp
      collect (let ((var (intern (car i)))
		    (val (cadr i)))
		(list 'setq var val))))

(loop for i in w
      collect (eval i))

(list (list "S1" " " s1)
      (list "S2" " " s2)
      (list "S3" " " s3)
      (list "S4" "(setq s4 (+ s1 s2)) " (setq s4 (+ s3 s2))))