/*
0.2 roelof's original plus added serial stuff from robin2
*/
const byte numChars = 32;
char receivedChars[numChars];
boolean newData = false;
#define NUMELEMENTS(x) (sizeof(x) / sizeof(x[0]))
byte dataPin = 2;
byte clockPin = 3;
byte latchPin = 4;
byte outputEnablePin = 6;
byte potPin1 = A0;
int value;
// timing in microseconds
unsigned long timerInterval = 2000;
unsigned long previousMicros = 0;
uint8_t data = 0;
uint16_t pulseWidths[] = { 200 , 400, 600, 800, 1000, 1200, 2000 };
uint8_t laPins[] = { 8, 9 };
void setup()
{
Serial.begin(115200);
Serial.println(F("74HC595 Software PWM 0.2"));
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(latchPin, OUTPUT);
for (uint8_t cnt = 0; cnt < NUMELEMENTS(laPins); cnt++)
{
pinMode(laPins[cnt], OUTPUT);
}
}
void loop()
{
unsigned long currentMicros = micros();
recvWithStartEndMarkers();
if (newData)
{
newData = false;
parseData();
}
if (currentMicros - previousMicros >= timerInterval)
{
previousMicros = currentMicros;
for (unsigned int i = 0; i < NUMELEMENTS(pulseWidths); i++)
{
//value = analogRead(potPin1);
//pulseWidths[0] = map(value, 0, 1023, 0, 2000);
if (pulseWidths[i] > 0)
{
data |= 1 << i;
}
}
}
else
{
for (unsigned int i = 0; i < NUMELEMENTS(pulseWidths); i++)
{
if (currentMicros - previousMicros >= pulseWidths[i])
{
data &= ~(1 << i);
}
}
}
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, data << 1);
digitalWrite(latchPin, HIGH);
}
void recvWithStartEndMarkers()
{
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false)
{
rc = Serial.read();
if (recvInProgress == true)
{
if (rc != endMarker)
{
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars)
{
ndx = numChars - 1;
}
}
else
{
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker)
{
recvInProgress = true;
}
}
}
void parseData()
{ // split the data into its parts
char* strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(receivedChars, ","); // get the first part - the string
uint8_t ledNum = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
int pwmVal = atoi(strtokIndx); // convert this part to an integer
pulseWidths[ledNum - 1] = pwmVal;
}