Puck.js v 2.1 a not turning on

Posted on
  • The red led flashes when the battery is inserted but pressing the button doesn't give a green LED ... or any other response ... and the puck is not recognized by my web-bluetooth-compatible computer.

    I ordered the two pucks in 11/2021 and this was their behavior when I first received them so I set them aside and abandoned the intended use.

    I'd like to get back to that project ... but the recommended reset and hard reset methods have no effect.

    The pucks recognize the battery ( properly inserted via the docs) and the red LED flashes ... but that's all I get.

    Is there some different reset method ... a way to see if these aren't actually DOA?

    Any help/response appreciated.

  • Hi,

    The red flash when the battery is inserted seems like a good sign...

    but pressing the button doesn't give a green LED ... or any other response

    You need to hold the button down while you insert the battery. Pressing the button after the battery is inserted will have no effect.

    Could that be the problem?

    the puck is not recognized by my web-bluetooth-compatible computer.

    The Pucks should be recognized out the box once the red LED has flashed. Do you have an Android phone/tablet or some other computer you could try? It's possible that there is some configuration issue on the PC you are using.

    If there are still issues, please could you record a video or how you do the reset and also what happens on the PC when you go to connect?

  • Thanks very much for that quick response ... and pressing the button while putting the baattery back in DID give me a flash of all the leds and then, only once, continued with a flaash of the green LED three times.

    I guess I missed or misunderstood the need to press the button AS the battery is being inserted.

    The puck still isn't recognized by my chromebook's pairing but it is recognized by my samsung phone ... although the phone says I need an app to use the device ... and also by the espruino web ide.

    Thanks!

    Do you know if there's an espruino version of the madgwick ahrs protocol?
    And the IDE says a new firmware is available. I have 2.09 and it's suggesting 2v16.

    Do you know the firmware upgrade method? I'll look in the docs as well.

    Thanks again!

  • and pressing the button while putting the baattery back in DID give me a flash of all the leds and then, only once, continued with a flaash of the green LED three times.

    Ok - so the green LED flash 3 times means it's started up into Espruino and hasn't loaded any code.

    If you let go of the button as soon as any lights light up, you'll enter bootloader mode (green LED on solid). Which I think is what you need to do to solve the other issue you posted: https://forum.espruino.com/conversations/382940/#comment16827704

    I guess I missed or misunderstood the need to press the button AS the battery is being inserted.

    You need to hold the button down, then insert the battery with the button still held...

    But to just use the Puck normally, holding the button isn't needed. Once the red LED flashes you should be ok to connect.

    The puck still isn't recognized by my chromebook's pairing

    No, it won't be. You need to go to espruino.com/ide and then connect from there - do not pair it from the OS bluetooth menu - and if you have done, you need to unpair it.

    There is a tutorial on getting started at https://www.espruino.com/Quick+Start+BLE#puckjs and I think it'd be worth going through that step by step

    Do you know if there's an espruino version of the madgwick ahrs protocol?

    For do you mean https://github.com/arduino-libraries/MadgwickAHRS/blob/master/src/MadgwickAHRS.cpp ?

    I'm not aware of an implementation but the code there looks quite straightforward (just a bunch of maths) so it would be almost copy/paste to get it running in Espruino (change float to var and remove f from the end of the numbers).

  • I've just converted the Madgwick code:

    // Based on https://github.com/arduino-libraries/MadgwickAHRS/blob/master/src/MadgwickAHRS.cpp
    const sampleFreqDef =  26.0;          // sample frequency in Hz
    const betaDef       =  0.1;            // 2 * proportional gain
    
    
    //============================================================================================
    // Functions
    function invSqrt(x) { return 1/Math.sqrt(x); }
    
    //-------------------------------------------------------------------------------------------
    // AHRS algorithm update
    
    class Madgwick {
      /*
        contains:
        
        roll, pitch, yaw (in radians)
      */
      constructor() {
        this.beta = betaDef;
        this.q0 = 1.0;
        this.q1 = 0.0;
        this.q2 = 0.0;
        this.q3 = 0.0;
        this.invSampleFreq = 1.0 / sampleFreqDef;
        this.anglesComputed = 0;
      }
    
     update(gx, gy, gz, ax, ay, az, mx, my, mz) {
    	var recipNorm;
    	var s0, s1, s2, s3;
    	var qDot1, qDot2, qDot3, qDot4;
    	var hx, hy;
    	var _2q0mx, _2q0my, _2q0mz, _2q1mx, _2bx, _2bz, _4bx, _4bz, _2q0, _2q1, _2q2, _2q3, _2q0q2, _2q2q3, q0q0, q0q1, q0q2, q0q3, q1q1, q1q2, q1q3, q2q2, q2q3, q3q3;
    
    	// Use IMU algorithm if magnetometer measurement invalid (avoids NaN in magnetometer normalisation)
    	if((mx == 0) && (my == 0) && (mz == 0)) {
    		this.updateIMU(gx, gy, gz, ax, ay, az);
    		return;
    	}
       
      var q0 = this.q0, q1 = this.q1, q2 = this.q2, q3 = this.q3;
    
    	// Convert gyroscope degrees/sec to radians/sec
    	gx *= 0.0174533;
    	gy *= 0.0174533;
    	gz *= 0.0174533;
    
    	// Rate of change of quaternion from gyroscope
    	qDot1 = 0.5 * (-q1 * gx - q2 * gy - q3 * gz);
    	qDot2 = 0.5 * (q0 * gx + q2 * gz - q3 * gy);
    	qDot3 = 0.5 * (q0 * gy - q1 * gz + q3 * gx);
    	qDot4 = 0.5 * (q0 * gz + q1 * gy - q2 * gx);
    
    	// Compute feedback only if accelerometer measurement valid (avoids NaN in accelerometer normalisation)
    	if(!((ax == 0.0) && (ay == 0.0) && (az == 0.0))) {
    
    		// Normalise accelerometer measurement
    		recipNorm = invSqrt(ax * ax + ay * ay + az * az);
    		ax *= recipNorm;
    		ay *= recipNorm;
    		az *= recipNorm;
    
    		// Normalise magnetometer measurement
    		recipNorm = invSqrt(mx * mx + my * my + mz * mz);
    		mx *= recipNorm;
    		my *= recipNorm;
    		mz *= recipNorm;
    
    		// Auxiliary variables to avoid repeated arithmetic
    		_2q0mx = 2 * q0 * mx;
    		_2q0my = 2 * q0 * my;
    		_2q0mz = 2 * q0 * mz;
    		_2q1mx = 2 * q1 * mx;
    		_2q0 = 2 * q0;
    		_2q1 = 2 * q1;
    		_2q2 = 2 * q2;
    		_2q3 = 2 * q3;
    		_2q0q2 = 2 * q0 * q2;
    		_2q2q3 = 2 * q2 * q3;
    		q0q0 = q0 * q0;
    		q0q1 = q0 * q1;
    		q0q2 = q0 * q2;
    		q0q3 = q0 * q3;
    		q1q1 = q1 * q1;
    		q1q2 = q1 * q2;
    		q1q3 = q1 * q3;
    		q2q2 = q2 * q2;
    		q2q3 = q2 * q3;
    		q3q3 = q3 * q3;
    
    		// Reference direction of Earth's magnetic field
    		hx = mx * q0q0 - _2q0my * q3 + _2q0mz * q2 + mx * q1q1 + _2q1 * my * q2 + _2q1 * mz * q3 - mx * q2q2 - mx * q3q3;
    		hy = _2q0mx * q3 + my * q0q0 - _2q0mz * q1 + _2q1mx * q2 - my * q1q1 + my * q2q2 + _2q2 * mz * q3 - my * q3q3;
    		_2bx = Math.sqrt(hx * hx + hy * hy);
    		_2bz = -_2q0mx * q2 + _2q0my * q1 + mz * q0q0 + _2q1mx * q3 - mz * q1q1 + _2q2 * my * q3 - mz * q2q2 + mz * q3q3;
    		_4bx = 2 * _2bx;
    		_4bz = 2 * _2bz;
    
    		// Gradient decent algorithm corrective step
    		s0 = -_2q2 * (2 * q1q3 - _2q0q2 - ax) + _2q1 * (2 * q0q1 + _2q2q3 - ay) - _2bz * q2 * (_2bx * (0.5 - q2q2 - q3q3) + _2bz * (q1q3 - q0q2) - mx) + (-_2bx * q3 + _2bz * q1) * (_2bx * (q1q2 - q0q3) + _2bz * (q0q1 + q2q3) - my) + _2bx * q2 * (_2bx * (q0q2 + q1q3) + _2bz * (0.5 - q1q1 - q2q2) - mz);
    		s1 = _2q3 * (2 * q1q3 - _2q0q2 - ax) + _2q0 * (2 * q0q1 + _2q2q3 - ay) - 4 * q1 * (1 - 2 * q1q1 - 2 * q2q2 - az) + _2bz * q3 * (_2bx * (0.5 - q2q2 - q3q3) + _2bz * (q1q3 - q0q2) - mx) + (_2bx * q2 + _2bz * q0) * (_2bx * (q1q2 - q0q3) + _2bz * (q0q1 + q2q3) - my) + (_2bx * q3 - _4bz * q1) * (_2bx * (q0q2 + q1q3) + _2bz * (0.5 - q1q1 - q2q2) - mz);
    		s2 = -_2q0 * (2 * q1q3 - _2q0q2 - ax) + _2q3 * (2 * q0q1 + _2q2q3 - ay) - 4 * q2 * (1 - 2 * q1q1 - 2 * q2q2 - az) + (-_4bx * q2 - _2bz * q0) * (_2bx * (0.5 - q2q2 - q3q3) + _2bz * (q1q3 - q0q2) - mx) + (_2bx * q1 + _2bz * q3) * (_2bx * (q1q2 - q0q3) + _2bz * (q0q1 + q2q3) - my) + (_2bx * q0 - _4bz * q2) * (_2bx * (q0q2 + q1q3) + _2bz * (0.5 - q1q1 - q2q2) - mz);
    		s3 = _2q1 * (2 * q1q3 - _2q0q2 - ax) + _2q2 * (2 * q0q1 + _2q2q3 - ay) + (-_4bx * q3 + _2bz * q1) * (_2bx * (0.5 - q2q2 - q3q3) + _2bz * (q1q3 - q0q2) - mx) + (-_2bx * q0 + _2bz * q2) * (_2bx * (q1q2 - q0q3) + _2bz * (q0q1 + q2q3) - my) + _2bx * q1 * (_2bx * (q0q2 + q1q3) + _2bz * (0.5 - q1q1 - q2q2) - mz);
    		recipNorm = invSqrt(s0 * s0 + s1 * s1 + s2 * s2 + s3 * s3); // normalise step magnitude
    		s0 *= recipNorm;
    		s1 *= recipNorm;
    		s2 *= recipNorm;
    		s3 *= recipNorm;
    
    		// Apply feedback step
    		qDot1 -= this.beta * s0;
    		qDot2 -= this.beta * s1;
    		qDot3 -= this.beta * s2;
    		qDot4 -= this.beta * s3;
    	}
    
    	// Integrate rate of change of quaternion to yield quaternion
    	q0 += qDot1 * this.invSampleFreq;
    	q1 += qDot2 * this.invSampleFreq;
    	q2 += qDot3 * this.invSampleFreq;
    	q3 += qDot4 * this.invSampleFreq;
    
    	// Normalise quaternion
    	recipNorm = invSqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
    	this.q0 = q0 * recipNorm;
    	this.q1 = q1 * recipNorm;
    	this.q2 = q2 * recipNorm;
    	this.q3 = q3 * recipNorm;
    	anglesComputed = 0;
    }
    
    //-------------------------------------------------------------------------------------------
    // IMU algorithm update
    
    updateIMU(gx, gy, gz, ax, ay, az) {
    	var recipNorm;
    	var s0, s1, s2, s3;
    	var qDot1, qDot2, qDot3, qDot4;
    	var _2q0, _2q1, _2q2, _2q3, _4q0, _4q1, _4q2 ,_8q1, _8q2, q0q0, q1q1, q2q2, q3q3;
      var q0 = this.q0, q1 = this.q1, q2 = this.q2, q3 = this.q3;
    
    	// Convert gyroscope degrees/sec to radians/sec
    	gx *= 0.0174533;
    	gy *= 0.0174533;
    	gz *= 0.0174533;
    
    	// Rate of change of quaternion from gyroscope
    	qDot1 = 0.5 * (-q1 * gx - q2 * gy - q3 * gz);
    	qDot2 = 0.5 * (q0 * gx + q2 * gz - q3 * gy);
    	qDot3 = 0.5 * (q0 * gy - q1 * gz + q3 * gx);
    	qDot4 = 0.5 * (q0 * gz + q1 * gy - q2 * gx);
    
    	// Compute feedback only if accelerometer measurement valid (avoids NaN in accelerometer normalisation)
    	if(!((ax == 0) && (ay == 0) && (az == 0))) {
    
    		// Normalise accelerometer measurement
    		recipNorm = invSqrt(ax * ax + ay * ay + az * az);
    		ax *= recipNorm;
    		ay *= recipNorm;
    		az *= recipNorm;
    
    		// Auxiliary variables to avoid repeated arithmetic
    		_2q0 = 2 * q0;
    		_2q1 = 2 * q1;
    		_2q2 = 2 * q2;
    		_2q3 = 2 * q3;
    		_4q0 = 4 * q0;
    		_4q1 = 4 * q1;
    		_4q2 = 4 * q2;
    		_8q1 = 8 * q1;
    		_8q2 = 8 * q2;
    		q0q0 = q0 * q0;
    		q1q1 = q1 * q1;
    		q2q2 = q2 * q2;
    		q3q3 = q3 * q3;
    
    		// Gradient decent algorithm corrective step
    		s0 = _4q0 * q2q2 + _2q2 * ax + _4q0 * q1q1 - _2q1 * ay;
    		s1 = _4q1 * q3q3 - _2q3 * ax + 4 * q0q0 * q1 - _2q0 * ay - _4q1 + _8q1 * q1q1 + _8q1 * q2q2 + _4q1 * az;
    		s2 = 4 * q0q0 * q2 + _2q0 * ax + _4q2 * q3q3 - _2q3 * ay - _4q2 + _8q2 * q1q1 + _8q2 * q2q2 + _4q2 * az;
    		s3 = 4 * q1q1 * q3 - _2q1 * ax + 4 * q2q2 * q3 - _2q2 * ay;
    		recipNorm = invSqrt(s0 * s0 + s1 * s1 + s2 * s2 + s3 * s3); // normalise step magnitude
    		s0 *= recipNorm;
    		s1 *= recipNorm;
    		s2 *= recipNorm;
    		s3 *= recipNorm;
    
    		// Apply feedback step
    		qDot1 -= this.beta * s0;
    		qDot2 -= this.beta * s1;
    		qDot3 -= this.beta * s2;
    		qDot4 -= this.beta * s3;
    	}
    
    	// Integrate rate of change of quaternion to yield quaternion
    	q0 += qDot1 * this.invSampleFreq;
    	q1 += qDot2 * this.invSampleFreq;
    	q2 += qDot3 * this.invSampleFreq;
    	q3 += qDot4 * this.invSampleFreq;
    
    	// Normalise quaternion
    	recipNorm = invSqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
    	this.q0 = q0 * recipNorm;
    	this.q1 = q1 * recipNorm;
    	this.q2 = q2 * recipNorm;
    	this.q3 = q3 * recipNorm;
    	anglesComputed = 0;
    }
    
    //-------------------------------------------------------------------------------------------
    // Fast inverse square-root
    // See: http://en.wikipedia.org/wiki/Fast_inverse_square_root
    
    //-------------------------------------------------------------------------------------------
    
    computeAngles() {
      var q0 = this.q0, q1 = this.q1, q2 = this.q2, q3 = this.q3;
    	this.roll = Math.atan2(q0*q1 + q2*q3, 0.5 - q1*q1 - q2*q2);
    	this.pitch = Math.asin(-2 * (q1*q3 - q0*q2));
    	this.yaw = Math.atan2(q1*q2 + q0*q3, 0.5 - q2*q2 - q3*q3);
    	this.anglesComputed = 1;
    }
    }
    
    
    var m = new Madgwick();
    var mag = {x:0,y:0,z:0};
    Puck.magOn(40);
    Puck.on('mag', function(xyz) {
      mag = xyz;
    });
    Puck.on('accel', function(a) {
      m.update( 
        a.gyro.x/134, a.gyro.y/134, a.gyro.z/134,
        a.acc.x/8192, a.acc.y/8192, a.acc.z/8192,
        mag.x, mag.y, mag.z );
      m.computeAngles();
    });
    Puck.accelOn(sampleFreqDef);
    
    // Check m.roll, m.yaw, m.pitch (in radians)
    

    If this works ok I'm very happy to turn it into a library.

    It seems to work well here - if anything it's just a shame that there's no absolute position measurement built in here - but the actual roll/pitch/yaw looks like it works ok

  • WoW! Thanks So much for all of this great help! I'm working on getting the puck recognized in SensiML Data Capture Lab today.

  • Had stumbled upon this in the mean time. Seems to include a three.js visualizer and to use a serial interface. Haven't looked thur it. Just passing along the info. https://github.com/ZiCog/madgwick.js

  • It appears I need to do a custom device setup to interface with the SensiML Data Capture Lab. Looking into how to do that. So far, it seems I need to create a config file with BLE gatt info for the services to be monitored.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Puck.js v 2.1 a not turning on

Posted by Avatar for user152341 @user152341

Actions