Newbie Advice please

Hi all newbie here,
I’m new to all this and after buying a few boards for messing around I’d like to set up a small Halloween show with props and dimmable leds.

What I’m looking to do is

Control 8 props with 2 axis on each prop
Have led lights in each prop just on and off
Have 2 leds spots doing on of fade etc
Have an led strobe on one channel
Have ambient lights on 3 channels on off and fade etc

Any ideas
I have the uno r3, pca9685 for the servos, a 74hc595 to give me more outputs and a design of a random cross ssr relayboard for the leds, am I in the right area with parts/setup?
I have a pic of what I’ve got in mind for a board layout but can’t find an upload button

Thanks in advance

Andy

This should work I expect. You may need power drivers on the output of the 74hc595s to drive the leds as they appear to only have about 5MA of output drive and your leds (especially the spot lights) may draw more than that. There are many high current drivers available, Unl2003 for instanc e can do 1/2 amp or so. The upload button is 7th from the left on the reply tool bar. If you are a new user I think you can only do one upload per post though.

Peter

Thanks Peter

As you can see the relays I’ve used are just for show, and I haven’t included the servos on the pca9685 but you get the idea.

My leds are a mix of strips mixed lengths (single colour) 12v and 12v spots and a home brew strobe

I’ll be using vixen as the player and the uno as the controller

Hope the layout gives a better detail

Ah, I missed the relay part of this. They should have sufficient current capacity to drive your leds. They are however mechanical and thus subject to wear. You may be better to consider an electronic high current equivalent to avoid that (depending on how long you intend to run this).

Peter

I do have a solid state board that I’m designing/modding that will allow random cross for fading leds for use with this, I only used those relays in the layout as I couldn’t find the time to create my own part

Motor driver modules should do what you need. They provide a high current (anywhere from 800 ma to 2A or so for the cheap ones to 6 to 20Amps for more money) pwm output that should fade leds without you needing to build anything.

Peter

Interesting I’ll have a look at that and let you know thanks peter

I would like to jump in and say with the extremely low cost of Individually addressable LEDs I can not recommend using discrete LEDs for anything other than indicator for power. You can get ws2812b LEDs on little breakout boards at 10 for $0.99 on eBay/Aliexpress etc and you only have to use 1 pin to drive as many as you want (some limit based on the speed of the micro controller being used, an Arduino can drive 600 easily). They have built in PWM control and can produce 256million colors with minimal code using the fastLED.io library. That would only leave driving the other components directly from the micro controller. You could use an ESP8266 (maybe something like a nodemcu board). They can use almost every single pin for PWM so controlling the servos would be easy. That would be down to three components. The ESP8266 and the LEDs and the Servos. You also get the benefit of it being 32bit and running at 80mhz and being Arduino IDE compatible all at a price less than the Arduino UNO.

I should also say if i were building a bunch of individual animatronic items I would use an esp8266 esp-01 for each thing. They only have 4 gpio pins so they could control 3 servos and as many ws2812b leds as you wanted and are wifi enabled. You could use the esp8266-fastled-webserver as a start for the code and make them controllable from any device on your network or directly from things like smartphones. Each esp-01 is really cheap and with a small breakout board they are really easy to use. Also did I mention dirt cheap. I use them with these breakout boards all the time to control LED projects.
https://www.aliexpress.com/item/OPEN-SMART-ESP8266-Serial-Wi-Fi-Wireless-ESP-01-Adapter-Module-3-3V-5V-Compatible-for/32793689441.html

They only breakout 2 of the gpio pins directly but they have level shifting from/to 3.3v/5v as well as a voltage regulator. Since it only has the two pins you could only control 1 servo and a 1000 or so ws2812b LEDs.

Edit: $5 for the esp-01 with the breakout board.

Even cheaper if you shop around.

EDIT 2: I haven’t mentioned the memory yet. The ESP-01 has 1mb flash from most places and the esp12 has 4mb. Some models have even more.

Thanks sublimeartistry
Great bit of info there and something to look into for when I go to my Christmas displays, the only reason for me using the single colour leds was I have them in excess at the moment, off cuts from other jobs and projects, plus with it being my first attempt I didn’t want to get stuck with programming pixel events into sequences,

Any idea on where to start with the coding should I put the shift register in first then the pwm or vice versa?

Depends how comfortable you are with coding. If you are experienced either is good, if you are new to coding, then I’d probably start with the shift registers as being somewhat easier than the i2c library code to debug if it doesn’t work the first time. There are arduino tutorials on the net that show how to hook up and program the 74hc595 and likely Adafruit has a tutorial on the pca9685 to swipe code from.

Peter

Hi Peter
I have compiled my code reading through a few other posts and a bit of cutting and pasting, i’ve compiled for 8 channels at present even though i need a total of 12, it seems to have compiled correctly with no errors, would you care to take a look?

Sure I can look at it although the real test is whether it works with the hardware :slight_smile: . You probably need to use the preformatted text option (6th icon from the left in the reply tool bar) to keep the formatting. All your text needs to start with 4 spaces, but I find even with that it often screws up the formatting. If 8bits works, then 16 bits (to get the 12 you need) should be trivial if you daisy chain the shift registers. Just call the code that loads them twice, first time for the end 8 bits and the second time with the first 8 bits.

Peter

you can also use code blocks.

    [code]
    your code goes here
    [/code]

To show that I used a code block.

you can also use a quote block.

cheers guys,
heres what i have


int SER_Pin = 10;   //pin 14 on the 75HC595
int RCLK_Pin = 9;  //pin 12 on the 75HC595
int SRCLK_Pin = 8; //pin 11 on the 75HC595

//How many of the shift registers - change this
#define number_of_74hc595s 1

//do not touch
#define numOfRegisterPins number_of_74hc595s * 8

boolean registers[numOfRegisterPins];

void setup(){
  pinMode(SER_Pin, OUTPUT);
  pinMode(RCLK_Pin, OUTPUT);
  pinMode(SRCLK_Pin, OUTPUT);


  //reset all register pins
  clearRegisters();
  writeRegisters();
}               


//set all register pins to LOW
void clearRegisters(){
  for(int i = numOfRegisterPins - 1; i >=  0; i--){
     registers[i] = LOW;
  }
  writeRegisters();
} 


//Set and display registers
//Only call AFTER all values are set how you would like (slow otherwise)
void writeRegisters(){

  digitalWrite(RCLK_Pin, LOW);

  for(int i = numOfRegisterPins - 1; i >=  0; i--){
    digitalWrite(SRCLK_Pin, LOW);

    int val = registers[i];

    digitalWrite(SER_Pin, val);
    digitalWrite(SRCLK_Pin, HIGH);

  }
  digitalWrite(RCLK_Pin, HIGH);

}

//set an individual pin HIGH or LOW
void setRegisterPin(int index, int value){
  registers[index] = value;
}

void loop(){
  setRegisterPin(0, LOW);
  setRegisterPin(1, HIGH);
  setRegisterPin(2, LOW);
  setRegisterPin(3, HIGH);
  setRegisterPin(4, LOW);
  setRegisterPin(5, HIGH);
  setRegisterPin(6, LOW);
  setRegisterPin(7, HIGH);
  setRegisterPin(8, LOW);
  writeRegisters();
  delay(500);
  clearRegisters();
  setRegisterPin(0, HIGH);
  setRegisterPin(1, LOW);
  setRegisterPin(2, HIGH);
  setRegisterPin(3, LOW);
  setRegisterPin(4, HIGH);
  setRegisterPin(5, LOW);
  setRegisterPin(6, HIGH);
  setRegisterPin(7, LOW);
  setRegisterPin(8, HIGH);
  writeRegisters();
  delay(500);
  clearRegisters();

}

ive had a look at another one for the pwm servo control from adafruit, it compiles on its own but when i try and combine the 2 i end up with errors do i put in 2 void setups of combine the code under a single void setup header and the same on the loops

At a quick look I don’t see anything obviously wrong, but as I said the test is to try it with real hardware, if it works you are good.

In general you want the setup to run once before the loop starts to initialize everything and then the work all takes place inside the loop forever (or until you hit reset or power off anyway), so yes you want to add the stuff from the adafruit setup to the end of your setup and their loop code at the end of your loop so in one cycle of the loop your shift regisiter code runs and then the adafruit code runs after that and the two continue running one after the other for ever. If statements in your loop control how changes take place.

Peter

Marvellous Peter thanks im just waiting on my 74hc’s arriving hopefully thatll be tomorrow, but then again, this is the Uk and it can be anytime lol

Hi Peter can i have a bit more help please
ive compiled my code from the internet for the servos and ive tested it and they spin a preprogrammed amount into the code, how can i leave the preprogrammed amount blank ready for the unit to accept an amount from an external program (vixen) to drive the servos

also i need to set the servos to certain channel numbers within vixen any ideas how to assign this here’s my code for test

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// you can also call it with a different address you want
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
// you can also call it with a different address and I2C interface
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(&Wire, 0x40);

// Depending on your servo make, the pulse width min and max may vary, you 
// want these to be as small/large as possible without hitting the hard stop
// for max range. You'll have to tweak them as necessary to match the servos you
// have!
#define SERVOMIN  150 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  600 // this is the 'maximum' pulse length count (out of 4096)

// our servo # counter
uint8_t servonum = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("8 channel Servo test!");

  pwm.begin();
  
  pwm.setPWMFreq(60);  // Analog servos run at ~60 Hz updates

  delay(10);
}

// you can use this function if you'd like to set the pulse length in seconds
// e.g. setServoPulse(0, 0.001) is a ~1 millisecond pulse width. its not precise!
void setServoPulse(uint8_t n, double pulse) {
  double pulselength;
  
  pulselength = 1000000;   // 1,000,000 us per second
  pulselength /= 60;   // 60 Hz
  Serial.print(pulselength); Serial.println(" us per period"); 
  pulselength /= 4096;  // 12 bits of resolution
  Serial.print(pulselength); Serial.println(" us per bit"); 
  pulse *= 1000000;  // convert to us
  pulse /= pulselength;
  Serial.println(pulse);
  pwm.setPWM(n, 0, pulse);
}

void loop() {
  // Drive each servo one at a time
  Serial.println(servonum);
  for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
    pwm.setPWM(servonum, 0, pulselen);
  }

  delay(500);
  for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
    pwm.setPWM(servonum, 0, pulselen);
  }

  delay(500);

  servonum ++;
  if (servonum > 1) servonum = 0;
}

The magic is all occurring here in this library call.

Variable servonum is the servo channel number and variable pulselen is the servo position (limited in this case to 150 to 600 out of a range from 0 to 4096 presumably because that is the range limit of the servo used). So if your program sets servonum to the channel it wants and pulselen to the position it wants and then calls pwm.setPWM the servo should move there.

Peter