STM34F4 LIS3DSH Accelerometer Code

Posted on
  • Anyone,

    Before anything, First Post....!

    Here is my first (copy-modify-paste) JS code. I took the "LIS302" accelerometer example and "made" it compatible with the "LIS3DSH" accelerometer that can be found in newer F4 boards. I added PWM to the LEDS so I could see transition. Things that I have not figured out yet:

    1.- Power On Reset (Combination of commands through control registers 4 & 6 maybe?)
    2.- Reading packages ONLY when they are READY (Combination of commands through control registers 3 & 6 maybe and digitalRead(E0)?)
    3.- Reading Temperature (I think I am not getting the Payload in the correct format)
    4.- Generate "STALL" using the internal tone generator within the "CS43L22" DAC (have not touch it, and I hope I2S is not necessary)

    NOTE:
    1.-I am integrating ESPRUINO to LabVIEW, as I believe it has great potential as a realtime, Interface unit.
    2.- never coded JS, so if you see better ways I could improve "my" code, I will really appreciated.
    2.- I am "PICO" backer!!! In the mean time, learning with the STM32F4 as much as I can.

    function onInit() {
    //  SPI1.send([0x20,0b00000000], E3); //CTRL_REG4 : POWER DOWN ???
    //  SPI1.send([0x25,0b10000001], E3); //CTRL_REG6 : BOOT, [0], [0], [0], [0], [0],  ???
    //  SPI1.send([0x23,0b11001000], E3); //CTRL_REG3 : DR_EN, IEA_HIGH, [0],[0], INT1_EN, [0], [X], POR_EN ???
      SPI1.send([0x20,0b00010111], E3); //CTRL_REG4 : 3.125Hz, (BDU_EN = 0?) ,Z-Y-X Enabled
      SPI1.send([0x24,0b00000000], E3); //CTRL_REG5 : Anti-Aliasing 800Hz, Scale +/- 2G, Self-Test Disabled, SPI 4 wire
    }
    
    var avrx=0.0, avry=0.0;
    function LIS3DSH() {
      
      var accx = SPI1.send([0xA9,0], E3)[1];
      var accy = SPI1.send([0xAB,0], E3)[1];
      var accz = SPI1.send([0xAD,0], E3)[1];
      var tmp  = SPI1.send([0x0C,0], E3)[1];
    //  var STAT = SPI1.send([0x27,0], E3)[1]; //STATUS REGISTER
      
      if (accx>127) accx-=256;
      if (accy>127) accy-=256;
      if (accz>127) accz-=256;
      
    //  var temp = parseInt(tmp, 2); 2's Complement???
      
      avrx     = 1.3636*accx;
      avry     = 1.3636*accy;
      avrz     = 1*accz;
    //  var INT2 = digitalRead(E1);
    //  var INT1 = digitalRead(E0);
    
      console.log('X='+avrx, 'Y='+avry, 'Z='+accz, 'Tmp='+tmp, "STAT="+STAT /* ,*'INT1='+INT1, 'INT2='+INT2 */);
    
      if    (accx > 0) {analogWrite(LED3, (accx*0.0015)),           digitalWrite(LED2,0);} // STARBOARD  (RED LED)
      else             {analogWrite(LED2, (Math.abs(accx)*0.0015)), digitalWrite(LED3,0);} // PORT       (GREEN LED)
      
      if    (accy > 0) {analogWrite(LED1, (accy*0.0015)),           digitalWrite(LED4,0);}  // FOWARD    (ORANGE LED)
      else             {analogWrite(LED4, (Math.abs(accy)*0.0015)), digitalWrite(LED1,0);}  // AFT       (BLUE LED)
      
    }
    onInit();setInterval(LIS3DSH, 250);
    

    DALP


    1 Attachment

  • Hi, thanks for posting up!

    I had no idea they'd changed the accelerometer. So does the LIS302DL code not work at all?

    1.- Power On Reset (Combination of commands through control registers 4 & 6 maybe?)

    Sounds like that's what you need - however I wonder if there's any real need to reset it?

    2.- Reading packages ONLY when they are READY (Combination of commands through control registers 3 & 6 maybe and digitalRead(E0)?)

    You might be able to use setWatch(function() { .. get data .. }, E0, { edge:"rising",repeat:true}) which will call the function as soon as the edge rises. You'd have to be careful not to get data too fast though - probably the most you'd want is 500Hz, probably less.

    3.- Reading Temperature (I think I am not getting the Payload in the correct format)

    Do you have any examples of what you get for the temperature value and what you'd expect the temperature to be?

    4.- Generate "STALL" using the internal tone generator within the "CS43L22" DAC (have not touch it, and I hope I2S is not necessary)

    I'm not quite sure what you mean here? I'm not 100% sure but I assumed that the DAC wasn't initialised by default, so would be ok being left alone.

    In terms of your code, it looks fine (looks like you're not using the avrx/y/etc as averages, but you'd need an avrz=0 outside the function if you were going to do that).

    If you wanted to make the SPI slightly faster, you might be able to fit all 3 queries into one command with:

      var d = SPI1.send([0xA9,0xAB,0xAD,0x0C,0], E3)[1];
      var accx = d[1], accy = d[2], accz = d[3], tmp = d[4];
    

    Whether that works depends on the chip though...

  • Hey Gordon,

    Thanks for your quick response!

    I had no idea they'd changed the accelerometer. So does the LIS302DL code not work at all?

    The 0x20 register is about the only one (there is a couple more) that is fully compatible with the LIS3DSH chip.... I should have noted that I if were to uncomment the other initialization registers on the LIS3DSH code, it will create unknown/undesirable behaviors on the LIS302DL.... Moreover, I hate to "dirty" the LIS302 you have already running and hope others looking for the LIS3DSH can find the appropriate app.

    So YES, your current code can run LIS3DSH at that level only!

    Sounds like that's what you need - however I wonder if there's any real need to reset it?

    I noticed that every time I tried to upload new code to the STM32F4, the board would take the code, but the LIS3DSH would not do anything: setInterval would pull data every time with the same payload regardless of whatever the angle the devices was. after that, I tried reseting the STM32F4 through command line (reset();) and still could not get the LIS3DSH to re-initialized. The only way I found efficient was trough full Power Down, that did the job! I wonder of that is a limitation of not having the real ESPRUINO board.

    If I could get the POR running it would actually be beneficial because on my end:

    I could update code and (cleanly and/or without concern) flush the old one on the fly from my LabVIEW application. I really want to use this accelerometer and DAC code as my test bed for PICO-LabVIEW integration at work on medical/testing devices! Getting this figured out will help me provide proof for it.

    2.- Reading packages ONLY when they are READY (Combination of commands through control registers 3 & 6 maybe and digitalRead(E0)?)

    Will try that this week! Cannot always play/have fun at work!!!

    3.- Do you have any examples of what you get for the temperature value and what you'd expect the temperature to be?

    If I run the code, and I get the payload straight from the register ("tmp="+tmp), i get a value of =255, regardless of changes temperature on the chip's surface.

    If I run the code, and I get the payload from the register to the complement 2's ("temp="+temp), I get a value of =NAN, regardless of changes temperature on the chip's surface.

    Let me mention I don't really know whether I am actually getting anything as the payload received is =255 rather than =1111 1111 for that same instance. I read somewhere that JS treats everything as a string(???) and conversion needs to be made between types.... I just went with the flow.

    I found a couple of C code over the internet after people questioning how to get this TEMP sensor running. Funny thing is all real answers came straight from ST employees... the only ones that could read their own spec sheets on how to mix&match registers!!!

    I'm not quite sure what you mean here? I'm not 100% sure but I assumed that the DAC wasn't initialised by default, so would be ok being left alone.

    I went dyslexic again! I meant to say "STALL Sound" as for the ones you would hear when and aircraft if at too much a pitch.... all that mumble own my end is I want to generate a tone from the DAC itself as the angle changes from a low to a high pitch. On the other hand, I saw our "SOUND" code and I will definitely test it... I wonder If I could share the analogWrite on 2 pins (LED/Speaker) somehow so there is no waist of resource.

    If you wanted to make the SPI slightly faster, you might be able to fit all 3 queries into one command.

    I like that a lot - Will add for sure. Can I use the same format on I2C?

    Thank you so much for this Platform...!

    NOTE: sorry for the late request but: Can we still add PICO boards on KICKSTARTER or do I need to do it trough you?

    DALP

  • ... Please apologize me for the 100 typos....

  • For the temperature value, 0xFF is usually sent when the accelerometer doesn't understand the command you've given it. The other possibility is that the temperature reading has to be enabled using one of the other registers, but I couldn't find any mention of that when I looked.

    Do you have any links to the other C code you mentioned? It might shed some light on why it's not working.

    The NaN is probably because parseInt(tmp, 2) actually parses the integer (255 I guess) as a binary number (the 2 means base 2). Because none of the digits are binary, you get NaN (not a number) returned.

    JavaScript does actually have a number type, but it automatically converts. Generally you wouldn't have to worry about converting between types though - especially in this case.

    "STALL Sound"

    For the DAC, it'll be a real struggle using the CS43L22 DAC from Espruino. I'd ignore it I'm afraid and would just use a PWM pin to give you a square wave of the relevant pitch, or use the Waveform class to play back an actual waveform.

    fit all 3 queries into one command.

    I'm afraid I2C doesn't work that easily, because generally you have to write and then read. I2C devices do tend to let you download blocks of data anyway though - you'd have to read the Datasheets.

    Pico boards

    I'm afraid the KickStarter has ended, so unless you already went for one you'll have to wait until after April when the boards should start to appear in distributors. You can sign up here and I'll let you know when they're available though.

  • Before I comment: It is hard to believe it has been approx. 9-10 months since I last posted/replied. Apologize me Gordon for leaving leaving this post inconclusive.

    Life has now given me back some free time (hopefully) for me to continue this project: I want to "Clean and Polish" the code as Gordon recommended. With that in mind, I got back into ESPRUINO.COM first thing to upgrade the firmware to the latest revision from the one I currently had installed (v 1.78). So went ahead and downloaded and burned v 1.80 (1.80.1?) into the chip to find out that the code I posted earlier would not run.

    First thing I did was to verify that the MEM Sensor was not fried because of heat, cold, dust. It was not the case, As I was able to install v 1.78 and saw the MEMS dumping data as it once did before.

    Secondly, re-installed v 1.80 (and v 1.80.a) to not see any data from the SPI port over the console. I even went and changed SPI1 to SPI2 just in case that was the situation. Nothing but "0's" on the console. It really sucks I don't have a logic analyzer to check what it is going on those pins.

    Regardless, I was able to get a lot done over this sensor and would like to share, but cannot due to this SPI code working on 1.78 and not 1.80 issue.

    I am still ignorant of JavaScript, this is why I find this platform the best way to learn it.

    Thanks in advance.

  • You're still doing this with the F4? Do you ever call SPI1.setup(...)? I didn't see that in the code you posted above - I guess it's possible that the default pins for SPI have changed for some reason.

    Maybe you could try software SPI just to narrow it down:

    var spi = new SPI();
    spi.setup({miso: yourpin, mosi:yourpin, sck:yourpin});
    ...
    var d = spi.send(...);
    
  • Gordon,

    Thank you! It did work on the F4 board. I will update this post soon.
    
  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

STM34F4 LIS3DSH Accelerometer Code

Posted by Avatar for DALP @DALP

Actions