Mark_wllms
Member since Apr 2021 • Last active Jul 2021Most recent activity
-
-
At the moment it is all working, but I am polling the sensor 10 times a second to look for wrist twist, which is putting a bit of a strain on battery life, even when the watch isn't being worn. I'll look into the 'movement' interrupt, but am unsure if this is specific to BMA423. It won't hurt to try. The datasheet implies you can set a threshold movement in each axis to trigger the interrupt.
-
- 22 comments
- 5,840 views
-
-
Thanks. I was just reading https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays when you replied! Much neater.
I suspect 103 was redundant, as it is really a pointer assignment, not a copy. -
This is current state of code - just enough to demonstrate working. Various things still need adding, e.g. events and scaling the accel vector.
/* Espruino module for BMA421/BMA423 motion sensor */ //delete the next line for module var exports={}; //create an instance - initialise if necessary (or just reconnect) function BMA421(_i2c) { this.i2c = _i2c; this.enabled = (this.checkstatus()==1); if (!this.enabled) this.initialise(); } BMA421.prototype.initialise = function() { //reset sensor this.writeReg(0x7E,0xB6); //disable power save this.writeReg(0x7C,0x00); this.loadConfig(); //Accl Enable this.writeReg(0x7D, 0x04); //Acc Config this.writeReg(0x40, 0b00101000); //Enable and Reset Step Counter - this will also enable power save this.resetSteps(); this.enabled = (this.checkstatus()==1); } //x and y are swapped - could remap in hardware BMA421.prototype.getAccel = function() { var acc = { x: 0, y: 0, z: 0 }; if (this.enabled) { var data = this.readBytes(0x12,6); acc.x = (data[3] << 8) | data[2]; if (acc.x > 32767) acc.x -= 65536; acc.y = (data[1] << 8) | data[0]; if (acc.y > 32767) acc.y -= 65536; acc.z = (data[5] << 8) | data[4]; if (acc.z > 32767) acc.z -= 65536; } return acc; } BMA421.prototype.getSteps = function() { if (this.enabled) { var steps = this.readBytes(0x1E,4); return (steps[3] << 24) + (steps[2] <<16) + (steps[1] << 8) + steps[0]; } else return 0; } //Temperature always seems to be 25 BMA421.prototype.getTemp = function() { if (this.enabled) { return this.readBytes(0x22,1)[0] +23; } else return -300; } //enables the step counter, disables the step detector BMA421.prototype.resetSteps = function() { this.writeReg(0x7C, 0x00);//Sleep disable var feature_config = new Uint8Array(70); feature_config = this.readFeatures(70); feature_config[0x3A + 1] = 0x34; this.writeFeatures(feature_config, 70); //Sleep Enable this.writeReg(0x7C, 0x03); } //burst write data to a register BMA421.prototype.writeReg = function(r,d) { this.i2c.writeTo(0x18,r,d); } //read a given number of bytes from a register BMA421.prototype.readBytes = function(r,l) { this.i2c.writeTo(0x18,r); return this.i2c.readFrom(0x18,l); } //read a single byte from a register BMA421.prototype.readReg = function(reg) { this.i2c.writeTo(0x18,reg); return this.i2c.readFrom(0x18,1)[0]; } //burst read bytes from the feature config BMA421.prototype.readFeatures = function(l) { this.i2c.writeTo(0x18,0x5E); return this.i2c.readFrom(0x18,l); } //burst write bytes to the feature config BMA421.prototype.writeFeatures = function(config) { this.i2c.writeTo(0x18,0x5E,config); } //Config file as a binary blob - write in chunks BMA421.prototype.loadConfig = function () { var buffer_size = 64; var config = new Uint8Array(buffer_size); //initialise config this.writeReg(0x59,0x00); for (var i=0;i<6144; i+=buffer_size) { config = require("Storage").read("bma421_config.bin",i,buffer_size); this.i2c.writeTo(0x18,0x5B, (i / 2) & 0x0F); this.i2c.writeTo(0x18,0x5C, (i / 2) >> 4); this.i2c.writeTo(0x18,0x5E,config); } //enable sensor features this.writeReg(0x59,0x01); } //LSB of status register is 1 for working BMA421.prototype.checkstatus = function() { return (this.readReg(0x2A) & 0x1F); } exports.connect = function(_i2c) { return new BMA421(_i2c); }
BTW, I have no experience of JavaScript, only C/Pascal/Delphi (and a little python), so I'm not convinced by the object model here at all.
-
-
Thanks. Tried to open whole file with Storage.readArrayBuffer but ran out of heap memory, so chunked instead. I will try a larger chunk to see what works, now I can see if I am successful.
I will upload code when I have tweaked it, and maybe submit somewhere as well. I am trying to write as a proper module, but I have zero JavaScript. It would help Pinetime owners, at least. I think only older P8s have BMA421.
-
Ok, going back to my original question:
I've taken the suggestion from @fanoush and just written a short module in javascript for the BMA421 from scratch. All it does it load the binary code to set up the step counter and then reads steps and xyz acceleration. It seems to all work, for not many lines of code, so I'm happy with that as an approach.
My eventual solution was just to turn the bytes from the config file into a binary file that I upload to Storage. I then read it in chunks (I don't think this really uses memory?) and write each chunk to the sensor. Everything else is very similar to the example code in the ATCWatcH project. The datasheet has several errors / omissions in it, but it helped to get started.
BMA421 doesn't have twist interrupts, so I will have to check that on an interval if I want to turn on the screen that way.
I have set up an M11 smart watch to run Espruino, and am having fun writing some watch apps for it.