View Single Post
  #1   Spotlight this post!  
Unread 21-05-2012, 08:38
gixxy's Avatar
gixxy gixxy is offline
Programming and Arduino Mentor
AKA: Gustave Michel III
FRC #3946 (Tiger Robotics)
Team Role: Mentor
 
Join Date: Nov 2011
Rookie Year: 2012
Location: Ruston, LA
Posts: 207
gixxy is on a distinguished road
Arduino Programming Mode Selection Help

So I am making an Arduino controlled, cyberpunk-ish, Pulsing LED Gauntlet. Basiclly it will have 4 set of 8 LEDs that are CharliePlexed (Wikipedia Link together.

So most of that is done except selecting which pattern to use. I basically need it to be run in checkTimers() in the code below.

At first I was going to make an array of pointers to the functions and use a short that was sent to the object as the index. However I couldn't get it to work because these are Member functions...

I really DON'T want to make a giant switch case for this when being fast is more important if i can help it, but if that is the only way, just say so.

So here is the C++ header for controlling the strips:
Code:
/*
||
|| @file 	CharliePulser.cpp
|| @version	1.0
|| @author	Gus Michel
|| @contact	gus3@michelfamily.org
||
|| @description
|| | Provide an easy way of pulsing and controlling LED arrays that are charlieplexed
|| #
||
|| @license
|| | This library is free software; you can redistribute it and/or
|| | modify it under the terms of the GNU Lesser General Public
|| | License as published by the Free Software Foundation; version
|| | 2.1 of the License.
|| |
|| | This library is distributed in the hope that it will be useful,
|| | but WITHOUT ANY WARRANTY; without even the implied warranty of
|| | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
|| | Lesser General Public License for more details.
|| |
|| | You should have received a copy of the GNU Lesser General Public
|| | License along with this library; if not, write to the Free Software
|| | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
|| #
||
*/
#ifndef CHARLIEPULSER_H
#define CHARLIEPULSER_H


#include <math.h>
#include "CharlieLed.h"
#include "Arduino.h"
#include "TimeKeeper.h"


class CharliePulser {
	public:
	    	CharliePulser(
			CharlieLed LEDs[],
			short numleds,
			short PINs[],
			short numpins,
			unsigned long time
	    	);//CONSTRUCTOR
		void setTime(int time);			//Set Timer between steps
		void checkTimers();			//Check Timers (for Timeing of LED steps and Pulsing of multipule LEDs)
	private:
		short currentStep;			//The Current Step in the Mode (to allow for timing)
		short currentLed;			//The Current LED (for pulsing multipule LEDs back and forth)
		
		
		unsigned long stepTime;			//The Time per step
		unsigned long ledTime;			//The Time between rerunning the current LED
		unsigned long modeTime;			//The Time between rerunning the current step
		
		CharlieLed *leds;			//Array of CharlieLeds in the CharliePulser
		short numLeds;				//The Number of LEDs in the array
		short* pins;				//Array of Pins the Pulser consistes of
		short numPins;				//The Number of Pins in the Array
		short center;				//The Center LED
		
		TimeKeeper *modeTimer;			//Timer for repeating the current step. (repeat constantly)
		TimeKeeper *stepTimer;			//Timer for Changing the step. (repeat at seprate interval)
		TimeKeeper *ledTimer;			//Timer for Changing the LED to turn on in the next step. (repeat constantly)
		
		void off();			//Turn off all LEDs
		void pulseCycle();		//Move the LEDs back and forth in a line
		void pulseForward();		//Move the LEDs forward in a line
		void pulseBackward();		//Move the LEDs backward in a line
		void starCycle();		//Move the LEDs to and fro from the center
		void starIn();			//Move the LEDs into the center from edges
		void starOut();			//Move the LEDs out-to the edges from the center
		void crissCross();		//Move the LEDs aross whole array.
		
		void ledChanger();		//Handles Cycling of LEDs when multipule are needed on at once.
		void stepChanger();		//Handles Cycling step of Mode at timed interval
		void light(short led);		//Handles Lighting a specified LED
};
#endif
Here is the CPP file
Code:
#include "CharliePulser.h"

CharliePulser::CharliePulser(
	CharlieLed LEDs[],
	short numleds,
	short PINs[],
	short numpins,
	unsigned long time
    ) {
   	leds = (CharlieLed*) calloc(numleds, sizeof(CharlieLed));
	for(short i = 0; i < numleds; i++) {
		leds[i] = LEDs[i];
	}
	numLeds = numleds;
	
	pins = (short*) calloc(numpins, sizeof(short));
	for(short i = 0; i < numpins; i++) {
		pins[i] = PINs[i];
	}
	numPins = numpins;
	
	center = (short) (ceil((double)numLeds/2));
	
	ledTime = (unsigned long) 1;
	modeTime = (unsigned long) 1;
	stepTime = (unsigned long) time;
	
	currentStep = 1;
	currentLed = 0;
	
	ledTimer = new TimeKeeper(ledTime);
	modeTimer = new TimeKeeper(modeTime);
	stepTimer = new TimeKeeper(stepTime);
}

void CharliePulser::checkTimers() {
	if(modeTimer->check()) {
		crissCross();
	}
	if(ledTimer->check()) {
		ledChanger();
	}
	if(stepTimer->check()) {
		stepChanger();
	}
}

void CharliePulser::ledChanger() {
	currentLed++;
	if(currentLed > 1) {
		currentLed = 0;
	}
}

void CharliePulser::stepChanger() {
	currentStep++;
	if(currentStep > numLeds*2) {
		currentStep = 1;
	}
}

void CharliePulser::light(short led) {
	for(short i = 0; i < numPins; i++) {
		pinMode(pins[i], INPUT);
	}
	for(short i = 0; i < numPins; i++) {
		if(leds[led].getVoltagePin() == pins[i]) {
			pinMode(pins[i], OUTPUT);
			digitalWrite(pins[i], HIGH);
		} else if(leds[led].getGroundPin() == pins[i]) {
			pinMode(pins[i], OUTPUT);
			digitalWrite(pins[i], LOW);
		}
	}
}



//PULSING PATTERNS
void CharliePulser::off() {
	for(short i = 0; i < numPins; i++) {
		pinMode(pins[i], INPUT);
	}
}

void CharliePulser::pulseCycle() {
	if(currentStep <= numLeds) {
		pulseForward();
	} else {
		pulseBackward();
	}
}

void CharliePulser::pulseForward() {
	if(currentStep <= numLeds) {
		light((short) currentStep-1);
	} else {
		light((short) (currentStep-numLeds)-1);
	}
}

void CharliePulser::pulseBackward() {
	if(currentStep <= numLeds) {
		light((short) (numLeds-currentStep));
	} else {
		light((short) (numLeds-(currentStep-numLeds)));
	}
}

void CharliePulser::starCycle() {
	if(currentLed == 0) {
		pulseForward();
	} else {
		pulseBackward();
	}
}

void CharliePulser::starIn() {
	if(currentStep > center) {
		currentStep = 1;
	}
	starCycle();
}

void CharliePulser::starOut() {
	if(currentStep < center || currentStep > center*2) {
		currentStep = center+1;
	}
	starCycle();
}

void CharliePulser::crissCross() {
	if(currentStep*2 == numLeds) {
		currentStep++;
	}
	if((currentStep-numLeds)*2 == numLeds) {
		currentStep++;
	}
	starCycle();
}
Here is the Arduino Sketch
Code:
#include <CharliePulser.h>
#include <CharlieLed.h>
#include <TimeKeeper.h>

unsigned long timer = 100;
short numleds = 8;
short numpins = 4;
short startMode = 0; //OFF

short leftGreenPins[4] = {22, 24, 26, 28};
short leftBluePins[4] = {23, 25, 27, 29};
short rightGreenPins[4] = {30, 32, 34, 36};
short rightBluePins[4] = {31, 33, 35, 37};

CharlieLed leftGreenLeds[12] = {
  CharlieLed(22, 24),
  CharlieLed(24, 22),
  CharlieLed(24, 26),
  CharlieLed(26, 24),
  CharlieLed(26, 28),
  CharlieLed(28, 26),
  CharlieLed(22, 26),
  CharlieLed(26, 22),
  CharlieLed(24, 28),
  CharlieLed(28, 24),
  CharlieLed(22, 28),
  CharlieLed(28, 22)
};
CharlieLed leftBlueLeds[12] = {
  CharlieLed(23, 25),
  CharlieLed(25, 23),
  CharlieLed(25, 27),
  CharlieLed(27, 25),
  CharlieLed(27, 29),
  CharlieLed(29, 27),
  CharlieLed(23, 27),
  CharlieLed(27, 23),
  CharlieLed(25, 29),
  CharlieLed(29, 25),
  CharlieLed(23, 29),
  CharlieLed(29, 23)
};
CharlieLed rightGreenLeds[12] = {
  CharlieLed(30, 32),
  CharlieLed(32, 30),
  CharlieLed(32, 34),
  CharlieLed(34, 32),
  CharlieLed(34, 36),
  CharlieLed(36, 34),
  CharlieLed(30, 34),
  CharlieLed(34, 30),
  CharlieLed(32, 36),
  CharlieLed(36, 32),
  CharlieLed(32, 36),
  CharlieLed(36, 32)
 };
CharlieLed rightBlueLeds[12] = {
  CharlieLed(31, 33),
  CharlieLed(33, 31),
  CharlieLed(33, 35),
  CharlieLed(35, 33),
  CharlieLed(35, 37),
  CharlieLed(37, 35),
  CharlieLed(31, 35),
  CharlieLed(35, 31),
  CharlieLed(33, 37),
  CharlieLed(37, 33),
  CharlieLed(31, 37),
  CharlieLed(37, 31)
 };

CharliePulser* leftGreen;
CharliePulser* leftBlue;
CharliePulser* rightGreen;
CharliePulser* rightBlue;

void setup() {
  leftGreen = new CharliePulser(
    leftGreenLeds,
    numleds,
    leftGreenPins,
    numpins,
    timer
  );
  leftBlue = new CharliePulser(
    leftBlueLeds,
    numleds,
    leftBluePins,
    numpins,
    timer
  );
  rightGreen = new CharliePulser(
    rightGreenLeds,
    numleds,
    rightGreenPins,
    numpins,
    timer
  );
  rightBlue = new CharliePulser(
    rightBlueLeds,
    numleds,
    rightBluePins,
    numpins,
    timer
  );
  
  free(leftGreenPins);
  free(leftBluePins);
  free(rightGreenPins);
  free(rightBluePins);
  free(leftGreenLeds);
  free(leftBlueLeds);
  free(rightGreenLeds);
  free(rightBlueLeds);
}

void loop() {
  leftGreen->checkTimers();
  leftBlue->checkTimers();
  rightGreen->checkTimers();
  rightBlue->checkTimers();
}
TimeKeeper uses the millis() function to check if a specified interval of time has passed, and CharlieLed just keeps track of how the leds are hooked up.

Any and all help is much appreciated.
__________________
Programmer - A creature known for converting Caffeine into Code.
Studying Computer Science @ Louisiana Tech University
Associate Consultant @ Fenway Group

2012-13: 3946 - Head of Programming, Electrical and Web
2014 - 3468 - Programming Mentor
2015 - Present - Lurker

Last edited by gixxy : 21-05-2012 at 08:45.