16 LED на PCA9685 с Adafruit_PWMServoDriver
- Войдите на сайт для отправки комментариев
Всем привет, нужна помощь с кодом под шилд PCA9685.
Сделал на arduino uno волнообразную мигалку c шим из 6 светодиодных лент, интенсивность которых зависит от ультрозвукового датчика HY-SRF05:
#include <Ultrasonic.h> Ultrasonic ultrasonic1(12, 13); Ultrasonic ultrasonic2(A2, A1); const byte ledPins[6] = {3,5,6,9,10,11}; void setup() { pinMode( ledPins, OUTPUT ); } void loop() { delay(100); int rotation1 = ultrasonic1.distanceRead(); int rotation2 = ultrasonic2.distanceRead(); rotation1 = constrain(rotation1,0,300); rotation2 = constrain(rotation2,0,300); int dim1 = map(rotation1,0,300,1,50); int dim2 = map(rotation2,0,300,1,50); if (rotation1 = 0) dim1 = 300; if (rotation2 = 0) dim2 = 300; int tot = dim1+dim2; int step; if (tot < 3 || tot > 50) step = 1; if (tot < 50 && tot > 30) step = 2; if (tot < 30 && tot > 10) step = 3; if (tot < 10 && tot > 5) step = 4; if (tot < 5) step = 5; for(int i=0; i<3; i=i+step){ analogWrite(ledPins[0], i); analogWrite(ledPins[1], i); analogWrite(ledPins[2], i); analogWrite(ledPins[3], i); analogWrite(ledPins[4], i); analogWrite(ledPins[5], i); delay(1); } for(int i=255; i>=0; i=i-step){ analogWrite( ledPins[0], (255-i)/dim1 ); analogWrite( ledPins[3], (255-i)/dim2 ); delay(1); } for(int i=255; i>=0; i=i-step){ analogWrite( ledPins[0], i/dim1 ); analogWrite( ledPins[3], i/dim2 ); analogWrite( ledPins[1], (255-i)/dim1 ); analogWrite( ledPins[4], (255-i)/dim2 ); delay(1); } for(int i=255; i>=0; i=i-step){ analogWrite( ledPins[1], i/dim1 ); analogWrite( ledPins[4], i/dim2 ); analogWrite( ledPins[2], (255-i)/dim1 ); analogWrite( ledPins[5], (255-i)/dim2 ); delay(1); } for(int i=255; i>=0; i=i-step){ analogWrite( ledPins[2], i/dim1 ); analogWrite( ledPins[5], i/dim2 ); delay(1); } }
Решив расширить шим с помощью PCA9685 столкнулся с проблемой адаптации кода.
чекнул примеры шим из библиотеки "Adafruit_PWMServoDriver.h":
void setup() { Serial.begin(9600); Serial.println("16 channel PWM test!"); pwm.begin(); pwm.setPWMFreq(1600); // This is the maximum PWM frequency // if you want to really speed stuff up, you can go into 'fast 400khz I2C' mode // some i2c devices dont like this so much so if you're sharing the bus, watch // out for this! Wire.setClock(400000); } void loop() { // Drive each PWM in a 'wave' for (uint16_t i=0; i<4096; i += 8) { for (uint8_t pwmnum=0; pwmnum < 16; pwmnum++) { pwm.setPWM(pwmnum, 0, (i + (4096/16)*pwmnum) % 4096 ); } #ifdef ESP8266 yield(); // take a breather, required for ESP8266 #endif } }
все ленты одновременно плавно гаснут по циклу, но когда изменяю значение pwmnum на нужный мне выход на плате, домпустим 1 или 3, реакции никакой, либо все ленты горят в половину.
Адптировал свой код под эту плату:
#include <Ultrasonic.h> #include <Wire.h> #include <Adafruit_PWMServoDriver.h> Ultrasonic ultrasonic1(12, 13); Ultrasonic ultrasonic2(A2, A1); Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); void setup() { Serial.begin(9600); Serial.println(); pwm.begin(); pwm.setPWMFreq(1600); Wire.setClock(400000); } void loop() { delay(1); int rotation1 = ultrasonic1.distanceRead(); int rotation2 = ultrasonic2.distanceRead(); rotation1 = constrain(rotation1,0,300); rotation2 = constrain(rotation2,0,300); int dim1 = map(rotation1,0,300,1,800); int dim2 = map(rotation2,0,300,1,800); if (rotation1 = 0) dim1 = 4096; if (rotation2 = 0) dim2 = 4096; int tot = dim1+dim2; int step; if (tot < 3 || tot > 50) step = 16; if (tot < 50 && tot > 30) step = 32; if (tot < 30 && tot > 10) step = 48; if (tot < 10 && tot > 5) step = 64; if (tot < 5) step = 80; for(int i=0; i<4096; i=i+step){ pwm.setPWM(0, 0, i); pwm.setPWM(1, 0, i); pwm.setPWM(2, 0, i); pwm.setPWM(3, 0, i); pwm.setPWM(4, 0, i); pwm.setPWM(5, 0, i); delay(1); } for(int i=4096; i>=0; i=i-step){ pwm.setPWM(0, 0, (4096-i)/dim1); pwm.setPWM(3, 0, (4096-i)/dim2); delay(1); } for(int i=4096; i>=0; i=i-step){ pwm.setPWM(0, 0, i/dim1); pwm.setPWM(3, 0, i/dim2); pwm.setPWM(1, 0, (4096-i)/dim1); pwm.setPWM(4, 0, (4096-i)/dim2); delay(1); } for(int i=4096; i>=0; i=i-step){ pwm.setPWM(1, 0, i/dim1); pwm.setPWM(4, 0, i/dim2); pwm.setPWM(2, 0, (4096-i)/dim1); pwm.setPWM(5, 0, (4096-i)/dim2); delay(1); } for(int i=4096; i>=0; i=i-step){ pwm.setPWM(2, 0, i/dim1); pwm.setPWM(5, 0, i/dim2); delay(1); } yield(); }
но вместо волнообразного последовательного переливания света от одной ленты к другой все ленты одновременно плавно загораются и резко гаснут. Не понимаю в чём ошибка и что я делаю не так.
Возможно я ошибаюсь, но в Вашей программе я не увидел адреса шилда PCA9685. Соответственно команды посылаются куда то.
Видимо адреса прописаны в библиотеке, но подключаю согласно со всеми примерами использования этой библиотеки с этим шилдом SCL - "A5"; SDA - "A4" ни в одном примеме программ не прописаны адреса амого шилда. Пробовал так же подключать на порты arduino "SDA" и "SCL" реакция та же.
Видимо адреса прописаны в библиотеке, но подключаю согласно со всеми примерами использования этой библиотеки с этим шилдом SCL - "A5"; SDA - "A4"
возможно, в библиотеке забит какой-то адрес, но вероятно он не совпадает с реальным адресом Вашего шилда. Судя по описанию, у этого шилда не фиксированный адрес, а может выбираться из диапазона 0x40-0x7F. Вам нужно запустить сканер и определить адрес шилда. а потом либо поправить его в библиотеке (если он там жестко прописан) - либо прописать иннициализации.
возможно, в библиотеке забит какой-то адрес, но вероятно он не совпадает с реальным адресом Вашего шилда. Судя по описанию, у этого шилда не фиксированный адрес, а может выбираться из диапазона 0x40-0x7F. Вам нужно запустить сканер и определить адрес шилда. а потом либо поправить его в библиотеке (если он там жестко прописан) - либо прописать иннициализации.
У этого шилда адрес должен задаваться перемычками (перепайками) на плате.
В коде прописано:
пустые скобки соответствуют адресу по умолчанию 0х40, что соответствует адресу шилда без запаеных перемычек.
Сканер подтвердил выдав устройство с адресом 0х40
Проблема была аппаратная, всё дело в питании. Почему-то когда запитал шилд отдельно (не от ардуино) всё стало работать и каждый из 16 каналов действуют. Но проблема с кодом осталось. Вместо плавного угосания светодиоды резко выключаются.
Переписал код. Проблема решена. Всем спасибо за поддержку)