Quantcast
Channel: Reprap Forum - Firmware - Marlin
Viewing all articles
Browse latest Browse all 12112

Re: Fan etc on external i2c-controller

$
0
0
v0.5 (first steps)

adds virtual ports 100-115 (maps to i2c ports 0-15) to m42 gcode

eg m42 p100 s255

new file pca9685.h add to main marlin directory
/**
 * Driver for the Philips PCA9685 LED driver.
 * Written by Peter Ellens Dec 2018
   Based on PCA9632 Driver by Robert Mendon Feb 2017.
 */

#ifndef __PCA9685_H__
#define __PCA9685_H__

/* Register addresses */
#define PCA9685_MODE1_REG           (byte)0x00
#define PCA9685_MODE2_REG           (byte)0x01
#define PCA9685_SUBADR1_REG         (byte)0x02
#define PCA9685_SUBADR2_REG         (byte)0x03
#define PCA9685_SUBADR3_REG         (byte)0x04
#define PCA9685_ALLCALL_REG         (byte)0x05
#define PCA9685_LED0_REG            (byte)0x06 // Start of LEDx regs, 4B per reg, 2B on phase, 2B off phase, little-endian
#define PCA9685_PRESCALE_REG        (byte)0xFE
#define PCA9685_ALLLED_REG          (byte)0xFA

// Mode1 register pin layout
#define PCA9685_MODE_RESTART        (byte)0x80
#define PCA9685_MODE_EXTCLK         (byte)0x40
#define PCA9685_MODE_AUTOINC        (byte)0x20
#define PCA9685_MODE_SLEEP          (byte)0x10
#define PCA9685_MODE_SUBADR1        (byte)0x08
#define PCA9685_MODE_SUBADR2        (byte)0x04
#define PCA9685_MODE_SUBADR3        (byte)0x02
#define PCA9685_MODE_ALLCALL        (byte)0x01

// Mode2 register pin layout
#define PCA9685_MODE_INVRT          (byte)0x10
#define PCA9685_MODE_OCH            (byte)0x08
#define PCA9685_MODE_TOTEM_POLE     (byte)0x04
#define PCA9685_MODE_OUTNE1         (byte)0x02
#define PCA9685_MODE_OUTNE0         (byte)0x01

#define PCA9685_PWM_FULL            (uint16_t)0x01000 // Special value for full on/full off LEDx modes

void pca9685_set_port_PWM8(const uint8_t port, uint16_t pwm);
void pca9685_set_port_PWM16(const uint8_t port, uint16_t pwm);

#endif // __PCA9685_H__

new file pca9685.cpp add to main marlin directory
/**
 * Driver for the Philips PCA9685 LED driver.
 * Written by Peter Ellens Dec 2018
   Based on PCA9632 Driver by Robert Mendon Feb 2017.
 */

#include "MarlinConfig.h"

#ifdef PCA9685

#include "pca9685.h"
#include 

#define PCA9685_MODE1_VALUE   PCA9685_MODE_ALLCALL|PCA9685_MODE_AUTOINC
#define PCA9685_MODE2_VALUE   PCA9685_MODE_TOTEM_POLE


#define PCA9685_ADDRESS             (byte)0x40

byte PCA9685_init = 0;

static void PCA9685_WriteRegister(const byte addr, const byte regadd, const byte value) {
  Wire.beginTransmission(addr);
  Wire.write(regadd);
  Wire.write(value);
  Wire.endTransmission();
}

static void PCA9685_WriteAllRegisters(const byte addr, const byte regadd, const byte value1, const byte value2, const byte value3, const byte value4) {
  Wire.beginTransmission(addr);
  Wire.write(regadd);
  Wire.write(value1);
  Wire.write(value2);
  Wire.write(value3);
  Wire.write(value3);
  Wire.endTransmission();
}
void pca9685_set_port_PWM16(const uint8_t port, uint16_t pwm) {
  byte on_l=0;
  byte on_h=0;
  byte off_l=0;
  byte off_h=0;


  Wire.begin();
  if (!PCA9685_init) {

    PCA9685_init = 1;
    PCA9685_WriteRegister(PCA9685_ADDRESS,PCA9685_MODE1_REG, PCA9685_MODE1_VALUE);
    PCA9685_WriteRegister(PCA9685_ADDRESS,PCA9685_MODE2_REG, PCA9685_MODE2_VALUE);
  }

  if (pwm > PCA9685_PWM_FULL ) pwm = PCA9685_PWM_FULL;

  if (pwm == PCA9685_PWM_FULL ) on_h = (PCA9685_PWM_FULL&0x1F00)>>8;
  else if (pwm == 0) off_h = (PCA9685_PWM_FULL&0x1F00)>>8;
  else {
    off_h = (pwm&0xF00)>>8;
    off_l = pwm&0xFF;
  }

  PCA9685_WriteAllRegisters(PCA9685_ADDRESS,PCA9685_LED0_REG+(4*port), on_h, on_l, off_h, off_l);
}

void pca9685_set_port_PWM8(const uint8_t port, uint16_t pwm) {
  if (pwm >= 255 ) pwm = 256;
  pca9685_set_port_PWM16(port, pwm<<4);
}

#endif // PCA9685

add this to Configuration.h
// Support for PCA9685 PWM driver
#define PCA9685

add this near the top of Marlin_main.cpp after #include "parser.h"
#ifdef PCA9685
#include "pca9685.h"
#endif

Next find the M42 section of code in Marlin_main.cpp
inline void gcode_M42() {
  if (!parser.seenval('S')) return;
  const byte pin_status = parser.value_byte();

  const pin_t pin_number = parser.byteval('P', LED_PIN);
  if (pin_number < 0) return;

  if (!parser.boolval('I') && pin_is_protected(pin_number)) return protected_pin_err();

  pinMode(pin_number, OUTPUT);
  digitalWrite(pin_number, pin_status);
  analogWrite(pin_number, pin_status);


and change it to
inline void gcode_M42() {
  if (!parser.seenval('S')) return;
  const byte pin_status = parser.value_byte();

  const pin_t pin_number = parser.byteval('P', LED_PIN);
  if (pin_number < 0) return;

  if (!parser.boolval('I') && pin_is_protected(pin_number)) return protected_pin_err();

  #ifdef PCA9685
  if (pin_number < 100) {
  #endif

  pinMode(pin_number, OUTPUT);
  digitalWrite(pin_number, pin_status);
  analogWrite(pin_number, pin_status);

  #ifdef PCA9685
  }
  else {
    pca9685_set_port_PWM8(pin_number-100, pin_status);
  }
  #endif


no idea how controller does the auto fan yet.... but this makes it somewhat useful.

Viewing all articles
Browse latest Browse all 12112

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>