PWM any pin with Arduino LilyPad for Dress

I am trying to set up a LilyPad on a dress as follows:

Two switches, which allow a possible of 4 combinations, to control the current state/function of LED’s.

17 LED’s (one is soldered to board on pin 13) that will fade according to a modified fade code to make it look like a heartbeat.

I want to be able to have something like this:https://playground.arduino.cc/Main/AnalogAndDigitalFireflies

with pins 2-19, excepting pin 13, which will only ever make a simple heartbeat type of pulse.

I don’t understand how the above project’s code works, but it seems that he managed to make a random PWM fade out of both the PWM and Digital pins.

I am trying to make the dress light up and fade on/off pins 2-19 (excepting 13) at random intervals, but I can’t find anything about how to do this.

I have tried extensive reading about the Fade, and PWM functions, and being new to this I can’t really understand the code mentioned above.

So far I have this:

 /* JOJO'S DRESS CODE
 *  This code is designed to connect the Arduino 328 (Lilypad clone)
 *  which contains 17 LED's (one red pin 13, and 16 on dress)
 *  Using 2 switches, a possibile 4 options can be built into this code. 
 *  
 *                     Mine are as follows: 
 *                       [-----------]
 *                       [   0 | 0   ]Option 1: No Lights
 *                       [   0 | 1   ]Option 2: HeartPulse only
 *                       [   1 | 0   ]Option 3: Starlight Fading random time, max 7 @ once
 *                       [   1 | 1   ]Option 4: Flash random pin, random (200,1000) max 7 @ once
 *                       [-----------]
 */



int maxon = 5; //Max

void setup() {
  // put your setup code here, to run once:

pinMode(0,INPUT);
pinMode(1,INPUT);
digitalWrite(1,LOW);//pulldown important to not steal precious power!
digitalWrite(0,LOW);//enables internal pulldown resistor
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(7,OUTPUT);
pinMode(8,OUTPUT);
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
pinMode(13,OUTPUT);
pinMode(14,OUTPUT);
pinMode(15,OUTPUT);
pinMode(16,OUTPUT);
pinMode(17,OUTPUT);
pinMode(18,OUTPUT);
pinMode(19,OUTPUT);


}

void loop(){
  //VARIABLES
  const byte LEDArray[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19};
  int pinCount =17;
  int switchA = A0;
  int switchB = A1;
  

///FIRST CASE, SWITCH 00, OPTION 1----------------------

if(digitalRead(switchA) == LOW){                           //if first switch off
 if(digitalRead(switchB) == LOW){                         //and second switch off also
  for(int thisPin = 0; thisPin < pinCount; thisPin++){    //cycle through all pins on array
    digitalWrite(LEDArray[thisPin],LOW);}                 //and turn them off
    digitalWrite(13,LOW);                                 //also, turn off pin 13 (red LED)
     }
    }

  //SECOND CASE, SWITCH 01, OPTION 2---------------------  
  if(digitalRead(switchA) ==LOW){                               //if first switch off        
    if(digitalRead(switchB) ==HIGH){                            // and second switch on 
      for (int thisPin = 0; thisPin < pinCount; thisPin++) {    //cycle through all pins on array
        digitalWrite(LEDArray[thisPin],LOW);}                    //and turn them off
        
        int brightness =0;                                      //create a variable, named brightness
        analogWrite(13,brightness);                             // give value to pin13, redLED
        if(brightness == 0 || brightness < 255){                //if 'brightness' is 0-254
          
          analogWrite(13,brightness);                           // value is shown via LED 
          brightness = brightness +1;                           //add 1 to value
          delay(10);                                            //delay to allow you to see "fade"
        }
      else if(brightness <=255 && brightness > 0){              //when it does not agree with above statement (is 255)
        brightness = brightness -3;                             //go down by 3's
        analogWrite(13,brightness);                             //apply brightness
        delay(5);                                               //wait half time of above. Will return to first statement when false
      }
      }
    }

    //THIRD CASE, SWITCH 10, OPTION 3-------------------------
    if(digitalRead(switchA) ==HIGH){
      if(digitalRead(switchB) ==LOW){
        digitalWrite(13,LOW);                                 //write this pin low, not needed
        int timeOff = random(1000,5000);                      //random time off parameters
        int timeOn = random(600,3001);                        //random time on parameters
        digitalWrite(LEDArray[random(0,18)],HIGH);           //write a random LEDArray pin as high***NEED PWM?!***
        delay(timeOn);                                       //NEED TO MAKE RANDOM FADE TIME, NOT TIME HIGH
       
        }
      }
    }

If anyone can help me put this in order, or point me in the right direction, I would really appriceate it. I would even settle for the LED’s just following option 4, and flashing on and off for a random set of time, but I don’t quite know how to do this AND set a limit as to how many come on at once.

If possible, I would like to make sure that 7 are on at any given time.

Thank you for your time. Andy

The Lilypad only has 6 hardware PWM pins. You can work around this limitation via software or hardware.

The software solution is to do software PWM. This allows you to generate a PWM signal on any pin of your Lilypad. I have used this library: https://github.com/per1234/PalatisSoftPWM for 15 PWM pins on the same microcontroller and you should be able to achieve 17. Since you need to control so many pins performance is extremely important and the Palatis library is by far the best of any Arduino softPWM library I have tried. The way PWM works is that the LED is actually blinking very fast. When the LED is on longer than it is off it appears to your eye to be brighter and vice versa. The trouble with software PWM compared to hardware PWM is that it is much slower, especially when you are trying to do software PWM on 17 pins with a microcontroller running at 8 MHz. When the LEDs are not moving relative to your eyes you will not be able to notice them blinking but when there is movement the flicker is more apparent. This may or may not be an issue for your project depending on what visual effect you're going for. You will want to tune the configuration of your code to achieve the highest possible frequency (set via PalatisSoftPWM.begin()). The project you referenced does a very crude form of software PWM that will achieve a much lower maximum frequency than the Palatis library.

A popular hardware solution to your problem is to use addressable LEDs such as WS2812 (or the SK6812 clones) (sold by Adafruit as "Neopixels"). With only two pins on your Lilypad you can control many of these LEDs. They have built in hardware that does the PWM so the Arduino only has to send the commands that control their brightness. The most popular library for controlling them is: https://github.com/FastLED/FastLED If you want a higher PWM frequency you can use the more expensive APA102. Although the RGB style is more common, both those options are available with only white LEDs.

There are also PWM ICs available that will effectively add more hardware PWM pins to your Arduino. These can be used to control standard LEDs.

Thank you SO much for your help! I installed the library, and thankfully the examples helped me set it up pretty easily, although I am still al little stuck.

If you could, would you help me with the proper sequence of events or commands to make the thing do as I like? I updated the code, and the comments at the end are where I’m stuck.

/* JOJO'S DRESS CODE
 *  This code is designed to connect the Arduino 328 (Lilypad clone)
 *  which contains 17 LED's (one red pin 13, and 16 on dress)
 *  Using 2 switches, a possibile 4 options can be built into this code. 
 *  
 *                     Mine are as follows: 
 *                       [-----------]
 *                       [   0 | 0   ]Option 1: No Lights
 *                       [   0 | 1   ]Option 2: HeartPulse only
 *                       [   1 | 0   ]Option 3: Starlight Fading random time, max 7 @ once
 *                       [   1 | 1   ]Option 4: Flash random pin, random (200,1000) max 7 @ once
 *                       [-----------]
 */

#include <PalatisSoftPWM.h>

SOFTPWM_DEFINE_CHANNEL(0, DDRD, PORTD, PORTD0);  //Arduino pin 0 - this pin is used for Serial so you will be unable to use Serial in your sketch if you use it for PWM
SOFTPWM_DEFINE_CHANNEL(1, DDRD, PORTD, PORTD1);  //Arduino pin 1 - this pin is used for Serial so you will be unable to use Serial in your sketch if you use it for PWM
SOFTPWM_DEFINE_CHANNEL(2, DDRD, PORTD, PORTD2);  //Arduino pin 2
/***************************************************************
 * PINS 3 AND 4 ARE FOR SWITCH ON LILYPAD
 * *************************************************************
 */

SOFTPWM_DEFINE_CHANNEL(5, DDRD, PORTD, PORTD5);  //Arduino pin 5
SOFTPWM_DEFINE_CHANNEL(6, DDRD, PORTD, PORTD6);  //Arduino pin 6
SOFTPWM_DEFINE_CHANNEL(7, DDRD, PORTD, PORTD7);  //Arduino pin 7
SOFTPWM_DEFINE_CHANNEL(8, DDRB, PORTB, PORTB0);  //Arduino pin 8
SOFTPWM_DEFINE_CHANNEL(9, DDRB, PORTB, PORTB1);  //Arduino pin 9
SOFTPWM_DEFINE_CHANNEL(10, DDRB, PORTB, PORTB2);  //Arduino pin 10
SOFTPWM_DEFINE_CHANNEL(11, DDRB, PORTB, PORTB3);  //Arduino pin 11
SOFTPWM_DEFINE_CHANNEL(12, DDRB, PORTB, PORTB4);  //Arduino pin 12
SOFTPWM_DEFINE_CHANNEL(13, DDRB, PORTB, PORTB5);  //Arduino pin 13
SOFTPWM_DEFINE_CHANNEL(14, DDRC, PORTC, PORTC0);  //Arduino pin A0
SOFTPWM_DEFINE_CHANNEL(15, DDRC, PORTC, PORTC1);  //Arduino pin A1
SOFTPWM_DEFINE_CHANNEL(16, DDRC, PORTC, PORTC2);  //Arduino pin A2
SOFTPWM_DEFINE_CHANNEL(17, DDRC, PORTC, PORTC3);  //Arduino pin A3
SOFTPWM_DEFINE_CHANNEL(18, DDRC, PORTC, PORTC4);  //Arduino pin A4
SOFTPWM_DEFINE_CHANNEL(19, DDRC, PORTC, PORTC5);  //Arduino pin A5

SOFTPWM_DEFINE_OBJECT(18);

void setup() {
  PalatisSoftPWM.begin(60);  // begin with 60 Hz PWM frequency
pinMode(3,INPUT);//switch 1 on Lilypad for control of LED function
pinMode(4,INPUT);//switch 2 on Lilypad for control of LED function
digitalWrite(3,LOW);
digitalWrite(4,LOW);
}

void loop() {

const byte LEDArray[] = {0, 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19};
int pinCount = 17;
int switchA = 3;
int switchB = 4;

//FIRST CASE, SWITCH 00, OPTION 1---------------------------------------------------

if(digitalRead(switchA)==LOW){
  if(digitalRead(switchB)==LOW){
   //-----------------ALL OFF-----------
      PalatisSoftPWM.allOff();
      digitalWrite(13,LOW);
    }
  }

//SECOND CASE, SWITCH 01, OPTION 2---------------------------------------------------

if(digitalRead(switchA) ==LOW){
  if(digitalRead(switchB)==HIGH){
    PalatisSoftPWM.allOff();

    //MAKE 13 PULSE
    int brightness = 0;
    analogWrite(13,brightness);
    if(brightness ==0 || brightness < 255){
      analogWrite(13,brightness);
      brightness = brightness +1;
      delay(10);
    }
      else if(brightness <= 255 && brightness > 0){
        brightness = brightness -3;
        analogWrite(13,brightness);
        delay(5);
      }
    }   
  }

//THIRD CASE, SWITCH 10, OPTION 3--------------------------------------------------
if(digitalRead(switchA)==HIGH){
  if(digitalRead(switchB)==LOW){
    int MaxOn = 7;
    int TimeOn = random(500,2001);
    int RPin = LEDArray[random(0,18)];
    //if number of pins on is not > 7 or MaxOn-----HOW DO I EXPRESS THIS?
    //Trying to fade up/down on a random pin (((time for either total fade or fade up is TimeOn)))
    //I don't know how to say this using the "PlatisSoftPWM.set(channel_idx, value)" command
  }
}

  
}

Since you started a new thread: http://forum.arduino.cc/index.php?topic=488785 lets continue discussion of your code there.

We can confine this thread to any further discussion of how to attain 17 fadeable LEDs using an Arduino LilyPad.

It's already discussed to some extent at the Playground page you linked but I think it's worth stressing that you should be careful not to exceed the current capabilities of the ATmega328P, as found in the datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdf Note that the 40 mA per pin maximum mentioned is the Absolute Maximum value:

Exposure to absolute maximum rating conditions for extended periods may affect device reliability.

20 mA is a safer per pin maximum. There are also maximum values for current sums, as noted in table 32-1 and the notes under 32-2. With so many LEDs it could be easy to exceed these maximums so some care with your resistor selections and programming are required. This is not a concern with the addressable LEDs as they are powered separately, the Arduino pins only provide the control signals. Of course with a wearable project you are also limited by your battery so current will always be a concern to some extent.