Learning how to use I2C


#1

Hi, I am new to uLisp and embedded programming.
I have gotten myself a micro:bit v2 and a capacitive xy touch board by DFRobot (mpr121).
I am now trying to learn how to do the I2C dance. To begin with I am trying to replicate a small arduino program from a tutorial.

#include <Wire.h>
int16_t data = 0;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  
  Wire.beginTransmission(0x5A);
  Wire.write(0x80);
  Wire.write(0x63);
  Wire.endTransmission();

  Wire.beginTransmission(0x5A);
  Wire.write(0x5E);
  Wire.write(0x0C);
  Wire.endTransmission();
}

void loop() {
  Wire.beginTransmission(0x5A);
  Wire.write(0x00);
  Wire.endTransmission();
  Wire.requestFrom(0x5A,2,true);
  data = (Wire.read() | Wire.read() << 8) & 0b0000111111111111;
  Serial.println(bitRead(data,4));
}

This is my attempt in uLisp so far

(defun setup ()
  (with-i2c (str #x5A)
            (write-byte #x80 str)
            (write-byte #x63 str))
  (with-i2c (str #x5A)
            (write-byte #x5E str)
            (write-byte #x0C str)))
(defun read ()
  (with-i2c (str #x5A t)
            (list
              (read-byte str)
              (read-byte str t))))
(defun read-capacitive-touch ()
  (setup)
  (loop
    (with-i2c (str #x5A)
              (write-byte #x00 str))
    (print (read))))
(read-capacitive-touch)

However it only seem to print (nil nil) even when I touch the board. I am a bit confused if I need to use restart-i2c or not.
I tried to use it like this

(defun read-capacitive-touch ()
  (setup)
  (loop
    (with-i2c (str #x5A)
              (write-byte #x00 str))
    (restart-i2c str t)
    (print (read))))

but it just returns Error: 'write-byte' undefined: str.

I am new to uLisp, but I have done a ton of Clojure programming in the past, so I might be making some wrong assumptions about how to program in lisp, -I should probably do some 101 lisp.

Would be nice if someone could point me in the right direction, of what I am missing. I am also quite new to electronics, so there are many sources of potential errors, so if I can at least exclude some of them :P.


#2

I think your Lisp is fine; it’s the I2C that is slightly wrong. I think you need to do:

(defun read-capacitive-touch ()
  (setup)
  (loop
   (with-i2c (str #x5A)
     (write-byte #x00 str)
     (restart-i2c str 2)
     (print (list
             (read-byte str)
             (read-byte str))))))

The restart-i2c call has to be made with an active i2c stream. I’ve also explicitly specified the number of bytes to read, although the way you’ve done it should work too.

Let me know if that works!


#3

ah that makes sense, I suppose the write-byte error was emitted by the restart-i2c which probably performs that under the hood.
I am gonna play around with this some more when I get home.
Thank you so much for your help!
I think uLisp is genius for rapid prototyping and learning, much better to prototype in than Rust which I had originally intended to use for prototyping and learning.


#4

You might also find it useful to look at the uLisp Sensor Library, which has several examples of interfacing to sensors with I2C.


#5

got it working! :D
The biggest issue and source of confusion was the fact that I was using the wrong address.
I should have used x5B and not x5A.

(defun setup ()
  (with-i2c (str 0 #x5B)
            (write-byte #x80 str)
            (write-byte #x63 str))
  (with-i2c (str 0 #x5B)
            (write-byte #x5E str)
            (write-byte #x0C str)))
(defun read ()
  (with-i2c (str 0 #x5B t)
            (list
              (read-byte str)
              (read-byte str t))))
(defun read-capacitive-touch ()
  (setup)
  (loop
    (with-i2c (str 0 #x5B)
              (write-byte #x00 str)
              (restart-i2c str 2)
              (print (list
                       (read-byte str)
                       (read-byte str))))))
(read-capacitive-touch)

Now I just need to get around reading that tome of a datasheet. Not really used to reading that kind of stuff, but now I at least have some confidence and know that I can get something working that I can poke around with.


#6

Great! Hope it goes well.