• Hi!

    Sorry for the question, I'm a kind of newbie...

    I was wondering if it's possible to connect Espruino Wi-Fi to the Adafruit 16-Channel 12-bit PWM/Servo Shield (https://learn.adafruit.com/adafruit-16-c­hannel-pwm-slash-servo-shield/overview).

    And, if it is, how to program it?
    Should I connect the SDA and SCL pins on the boards and use a code similar to this: https://www.espruino.com/arduino-motorsh­ield?

    Thank you!

  • Hey, no problem! Yes, it is possible to use it - I believe just connecting, GND, power, SDA and SCL would be enough.

    However it's not entirely simple as we don't currently have a library for the PCA9685 chip - so you'd have to send the I2C commands needed to control it using Adafruit's code (https://github.com/adafruit/Adafruit-PWM­-Servo-Driver-Library/blob/master/Adafru­it_PWMServoDriver.cpp) as a base.

    I can definitely help you to do that if you want (and I'm happy to make a library so that it is really easy to use code with it), but I don't have a PCA9685-based board here so it might require a little bit of trial and error!

    I should add that if you just want to control servos, you can just connect them straight to the Espruino WiFi - you should be able to control quite a few of them at a time without issues.

  • Thank you for your kind reply, Gordon! :-)

    I am a frontend web developer (that's why I love Espruino), but as I said I am a newbie in electronics, hence I am not sure to be able to do what you are suggesting.

    I know I can control servos directly from Espruino (already successfully done!), but I am trying to learn something new reusing hardware from previous experiments with different microcontrollers.

    By the way, I would like to try to "translate" Adafruit c++ code to a module for Espruino, avoiding to bother you with my personal experiments! ;-)
    Could you please suggest me a way to start? Maybe the code of another module you already ported into js for Espruino?

    I definitely wanna deepen this stuff. Maybe the libs/README.md file (https://github.com/espruino/Espruino/blo­b/master/libs/README.md) could be a starting point.

  • Great! In this case you should be able to do what you want in normal JavaScript, so actually delving into Espruino itself isn't needed - maybe that link should mention it?

    What you really need is: http://www.espruino.com/Writing+Modules

    The modules that use I2c (http://www.espruino.com/I2C#using-i2c) are a good start - and the code for them is usually here: https://github.com/espruino/EspruinoDocs­/tree/master/devices

    To get you started, just copy/paste this into the Web IDE:

    Modules.addCached("pca9685_servo",functi­on() {
    var C = {
    PCA9685_SUBADR1 : 0x2,
    PCA9685_SUBADR2 : 0x3,
    PCA9685_SUBADR3 : 0x4,
    PCA9685_MODE1 : 0x0,
    PCA9685_PRESCALE : 0xFE,
    LED0_ON_L : 0x6,
    LED0_ON_H : 0x7,
    LED0_OFF_L : 0x8,
    LED0_OFF_H : 0x9,
    ALLLED_ON_L : 0xFA,
    ALLLED_ON_H : 0xFB,
    ALLLED_OFF_L : 0xFC,
    ALLLED_OFF_H : 0xFD
    };
    function PWMServoDriver(i2c) {
      this.i2c = i2c;
      this.addr = 0x40;  
      this.reset(()=>{
        this.setPWMFreq(1000);
      });
    }
    PWMServoDriver.prototype.write = function(r,d) {
      this.i2c.writeTo(this.addr,r,d);
    };
    PWMServoDriver.prototype.read = function(r) {
      this.i2c.writeTo(this.addr,r);
      return this.i2c.readFrom(this.addr,1)[0];
    };
    PWMServoDriver.prototype.reset = function(callback) {
      this.write(C.PCA9685_MODE1, 0x80);
      if (callback) setTimeout(callback,10);
    };
    PWMServoDriver.prototype.setPWM = function(num,on,off) {
      this.i2c.writeTo(this.addr,
                       C.LED0_ON_L+4*num,
                       on, on>>8,
                       off,off>>8 );
    };
    PWMServoDriver.prototype.setPWMFreq = function(freq) {
     // FIXME
    };
    exports.connect = function(i2c) {
      return new PWMServoDriver(i2c);
    };
    });
    
    var i2c = new I2C(); // software I2C
    i2c.setup({sda:SDA_PIN, scl:SCL_PIN});
    var servo = require("pca9685_servo").connect(i2c);
    

    So you need to implement setPWMFreq, but the general outline of what you need should be there for the other stuff. I did setPWM because Espruino can do it a bit more tidily than Arduino can.

    Other thing to note is that servos don't run at 1000Hz (the default) so you have to use Adafruit's example: https://github.com/adafruit/Adafruit-PWM­-Servo-Driver-Library/blob/master/exampl­es/servo/servo.ino

    Part of me thinks it's worth just setting it to 60Hz by default and adding a 'setServo' function as well though. Most people are going to use this board/chip for servos anyway :)

  • Wow! A lot of stuff here! :-)
    Thank you a lot... I will try to use it!

  • Moduled.addCached("pca9685_servo",functi­on()
    Should that be:

    Modules.addCached("pca9685_servo",functi­on()

  • Thanks - just fixed! And I spotted some other issues too - I should have tested that!

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

Adafruit 16-Channel 12-bit PWM/Servo Shield - I2C interface

Posted by Avatar for Matteo @Matteo

Actions