Hi,
I need a fresh pair of eyes on my code. I am multiplexing a 43-segment display and turning segments on and off randomly. To achieve this, I am performing my own PWM by splitting each cycle into 64 “frames” and copying the previous one into the next each cycle so that new segments added to frame 0 are able to “fade in” by being copied into frames 1, 2, 3, 4 and so on as the cycles progress. When the segment is randomly selected again, I use an XOR function to flip the segment OFF for frame 0, and this OFF state gets copied to frames 1, 2, 3, 4 and so on so the segment fades out.
The problem is, something is illuminating segments that are 1 column over from activated segments. In other words, another segment illuminates exactly 1 column over from any segments properly in an ON state. The code is not complicated so I must be missing something straightforward and I’m just about at my wit’s end.
A few theories I have are: (1) the random number generator is not truly “random” and is generating the same segments, albeit one column over. I am calling random numbers every cycle so the sheer sample size may be revealing the pseudorandom nature of the generators. but I have tried this generator (2’s carry) as well as Arduino’s built in function random() and the phenomenon persists. (2) There is some rogue code somewhere copying columns to the next one over. But like I said the code is fairly simple and I can’t find anywhere where something like that could be happening.
const int columnPins[] = {3, A0, A1, A2, A3, A4, A5};
const int rowPins[] = {13, 5, 6, 9, 10, 11, 12};
byte colSegD[7];
int randGen;
byte colSegF[7];
byte fadeUpD[64][7];
byte fadeUpC[64][7];
byte fadeUpB[64][7];
byte newPatternD[7];
byte newPatternC[7];
byte newPatternB[7];
unsigned long m_w = 1;
unsigned long m_z = 2;
unsigned long getRandom()
{
m_z = 36969L * (m_z & 65535L) + (m_z >> 16);
m_w = 18000L * (m_w & 65535L) + (m_w >> 16);
return (m_z << 16) + m_w; /* 32-bit result */
}
void setup() {
m_w = analogRead(A8);
m_z = analogRead(A8);
//Serial.begin(9600);
// while (! Serial);
pinMode(A8, INPUT); //set random seed pin as input
randomSeed(analogRead(A8));
for (int i = 0; i < 7; i++) //set pins as outputs
{
pinMode(rowPins[i], OUTPUT);
pinMode(columnPins[i], OUTPUT);
}
colSegD[0] = B00000001;
colSegF[1] = B10000000;
colSegF[2] = B01000000;
colSegF[3] = B00100000;
colSegF[4] = B00010000;
colSegF[5] = B00000010;
colSegF[6] = B00000001;
//set initial pattern
for (int colCount = 0; colCount < 7; colCount++)
{
for (int rowCount = 0; rowCount < 7; rowCount++)
{
if (getRandom() % 10 == 1) //futz with mod value to change periodicity of segments being toggled
{
if (rowCount == 0) { //if segment is activated, program direct port map into segment array
fadeUpC[0][colCount] |= B10000000;
}
if (rowCount == 1) {
fadeUpC[0][colCount] |= B01000000;
}
if (rowCount == 2) {
fadeUpD[0][colCount] |= B10000000;
}
if (rowCount == 3) {
fadeUpB[0][colCount] |= B00100000;
}
if (rowCount == 4) {
fadeUpB[0][colCount] |= B01000000;
}
if (rowCount == 5) {
fadeUpB[0][colCount] |= B10000000;
}
if (rowCount == 6) {
fadeUpD[0][colCount] |= B01000000;
}
}
}
}
}
void loop() {
for (int masterLoop = 1; masterLoop < 32000; masterLoop++) {
for (int level = 0; level < 64; level++) //At each power level, the segment will be activated/deactivated.
{
for (int col = 0; col < 7; col++)
{
//Main multiplexing port mapping--turn segments on and off per column
PORTF = colSegF[col];
PORTD = (fadeUpD[level][col] | colSegD[col]);
PORTB = fadeUpB[level][col];
PORTC = fadeUpC[level][col];
}
}
//turn off all segments during new segment generation and frame copying
PORTF = 0;
PORTD = 0;
PORTB = 0;
PORTC = 0;
//shift levels up and generate new pattern
for (int i = 63; i > 0; i--) //shift segments to next-longest illuminated slot
{
for (int x = 0; x < 7; x++)
{
fadeUpB[i][x] = fadeUpB[i-1][x];
fadeUpC[i][x] = fadeUpC[i-1][x];
fadeUpD[i][x] = fadeUpD[i-1][x];
//delay(10);
}
}
for (int x = 0; x < 7; x++) //reset new pattern arrays
{
newPatternB[x] = 0;
newPatternC[x] = 0;
newPatternD[x] = 0;
}
//Generate new pattern for frame 0
for (int colCount = 0; colCount < 7; colCount++)
{
for (int rowCount = 0; rowCount < 7; rowCount++)
{
if (getRandom() % 800 == 0)
{
if (rowCount == 0) { //if segment is activated, program direct port map into fade up matrix
newPatternC[colCount] |= B10000000;
}
if (rowCount == 1) {
newPatternC[colCount] |= B01000000;
}
if (rowCount == 2) {
newPatternD[colCount] |= B10000000;
}
if (rowCount == 3) {
newPatternB[colCount] |= B00100000;
}
if (rowCount == 4) {
newPatternB[colCount] |= B01000000;
}
if (rowCount == 5) {
newPatternB[colCount] |= B10000000;
}
if (rowCount == 6) {
newPatternD[colCount] |= B01000000;
}
}
}
}
//toggle segments
for (int col =0; col < 7; col++) {
fadeUpB[0][col] ^= newPatternB[col];
fadeUpC[0][col] ^= newPatternC[col];
fadeUpD[0][col] ^= newPatternD[col];
}
}
}