Led scan matrix

Goeiedag, ben ik weer.

momenteel ben ik bezig met een project. en de bedoeling is om zo vele mogelijk RGB leds zonder enige IC's tegebruiken, ik gebruik wel transistors. EN! ze moeten werken doormidel van PWM.

Het probleem wat ik nu heb is dat als ik alle leds uit set en een loopje op 1 Led laat lopen.
dan heb ik altijd dat er een andere led tog heeeeel! ligt mee dimmed. wat dus een probleem is hij hoor niet mee tedimmen.

zo dra alle leds aan staan lijkt het gewoon goed tewerken.

en er zit een delayMicroseconds() in die ik ook graag elegant wil weg werken.

meschien dat jullie effe een oogje op mijn code willen werpen en me in de goeie richting kunnen duwen.
en ik gebruik momenteel de Arduino mega voor dit project.

hier een simpele foto hoe het is aan gesloten.

Fototje

en de code die ik nu heb

#define NUM_PLAYBACK 2
#define NUMBER_OF_OUTPUTS 36
#include "OutputValue.h"
OutputValue OV;

const uint16_t chase[] = {3,
                          18, 1000, 1000, 0, 255, 1, 0, 2, 0, 3, 0, 4, 0, 5, 255, 6, 0, 7, 255, 8, 0, 9, 255, 10, 0, 11, 0, 12, 0, 13, 0, 14, 255, 15, 0, 16, 255, 17, 0,
                          18, 750, 500, 0, 0, 1, 255, 2, 0, 3, 255, 4, 0, 5, 0, 6, 0, 7, 0, 8, 255, 9, 0, 10, 255, 11, 0, 12, 255, 13, 0, 14, 0, 15, 0, 16, 0, 17, 255,
                          18, 500, 0, 0, 0, 1, 0, 2, 255, 3, 0, 4, 255, 5, 0, 6, 255, 7, 0, 8, 0, 9, 0, 10, 0, 11, 255, 12, 0, 13, 255, 14, 0, 15, 255, 16, 0, 17, 0
                         };

const uint16_t chase1[] = {3,
                           18, 1000, 750, 18, 255, 19, 0, 20, 0, 21, 0, 22, 0, 23, 255, 24, 0, 25, 255, 26, 0, 27, 255, 28, 0, 29, 0, 30, 0, 31, 0, 32, 255, 33, 0, 34, 255, 35, 0,
                           18, 1000, 750, 18, 0, 19, 255, 20, 0, 21, 255, 22, 0, 23, 0, 24, 0, 25, 0, 26, 255, 27, 0, 28, 255, 29, 0, 30, 255, 31, 0, 32, 0, 33, 0, 34, 0, 35, 255,
                           18, 1000, 750, 18, 0, 19, 0, 20, 255, 21, 0, 22, 255, 23, 0, 24, 255, 25, 0, 26, 0, 27, 0, 28, 0, 29, 255, 30, 0, 31, 255, 32, 0, 33, 255, 34, 0, 35, 0
                          };

const uint16_t chase2[] = {3,
                           4, 1000, 1000, 0, 255, 2, 0, 3, 255, 5, 0,
                           4, 1000, 1000, 0, 0, 1, 255, 3, 0, 4, 255,
                           4, 1000, 1000, 1, 0, 2, 255, 4, 0, 5, 255
                          };


const uint8_t pin[] = {22, 24, 26, 28, 30, 32, 34, 36}; // row of colom geen idee maar het werkt!
const uint8_t pin1[] = {2, 3, 5, 6, 7, 8, 9, 10}; // row of colom geen idee maar het werkt!
const uint8_t outputPatch[6][6] = {
  {0, 1, 2, 18, 19, 20},
  {3, 4, 5, 21, 22, 23},
  {6, 7, 8, 24, 25, 26},
  {9, 10, 11, 27, 28, 29},
  {12, 13, 14, 30, 31, 32},
  {15, 16, 17, 33, 34, 35}
};

void setup() {
  TCCR3B = (TCCR3B & 0xF8) | 0x01 ;
  TCCR4B = (TCCR4B & 0xF8) | 0x01 ;

  Serial.begin(9600);
  for (uint8_t x = 0; x < 8; x++) {
    pinMode(pin[x], OUTPUT);
  }
  for (uint8_t x = 0; x < 8; x++) {
    pinMode(pin1[x], OUTPUT);
  }
}

void loop() {
  OV.Playback(0, chase2);
  //OV.Playback(1, chase1);
  OV.Refresh();


  for (uint8_t x = 0; x < 6; x++) {
    digitalWrite(pin[x], HIGH);
    for (uint8_t y = 0; y < 6; y++) {
      analogWrite(pin1[y], OV.Output(outputPatch[y][x]));
    }
    delayMicroseconds(2778); // 2778
    digitalWrite(pin[x], LOW);
  }
}

en de outputValue.h is een library die ik heb gemaakt en zorgt er voor dat ik led door middel van Scenetime en Fadetime + value(chase[], chase1[], chase2[]) de leds een voor geprogrammerde loopje kan laten doen.

spirit:
Het probleem wat ik nu heb is dat als ik alle leds uit set en een loopje op 1 Led laat lopen.
dan heb ik altijd dat er een andere led tog heeeeel! ligt mee dimmed. wat dus een probleem is hij hoor niet mee tedimmen.

Kun je hier ook wat meer over vertellen ?
Is het altijd dezelfde LED die samen met de gewenste LED oplicht, of is het steeds dezelfde ?
Maakt het dan ook uit wat je precies laat zien (kleur) ?

Heb je ook condensatoren toegepast, en weerstanden, of heb je de LEDs direct aangesloten ?
Wellicht heb je last van capaciteiten door de draden waarmee je ze hebt verbonden.

Kun je hier ook wat meer over vertellen ?
Is het altijd dezelfde LED die samen met de gewenste LED oplicht, of is het steeds dezelfde ?
Maakt het dan ook uit wat je precies laat zien (kleur) ?

Ja het is altijd een led die in serie (PWM pin) staat met een andere led.

en het is me op gevallen dat als er een led van de bovenste rij op Blauw staat dan dimmed de onderste rij Heel ligt blauw mee, met Rood en Groen heb ik dit niet.

visa versa heb ik dit met Rood. en dan werken Blauw en groen gewoon goed.

Heb je ook condensatoren toegepast, en weerstanden, of heb je de LEDs direct aangesloten ?
Wellicht heb je last van capaciteiten door de draden waarmee je ze hebt verbonden.

condensatoren ? Nee
weerstanden ? Ja
LEDs direct aangesloten ? Nee

momenteel zit alles op een breadbord. zegt dat genoeg?

spirit:
hier een simpele foto hoe het is aan gesloten.

Fototje

Ik hoop dat er iemand hier is die dit snapt.......
Ik denk dat je toch wel een iets duidelijkere schema moet maken want dit zegt helemaal niets...

Beter schema inderdaad (inclusief transistors en weerstanden).

En wie weet heb je een fout in je bibliotheek, dus de code daarvoor kan ook wel handig zijn.

nouw hier is een betere versie hoop ik.

Link
oja en tussen arduino en transistor zit een 470 Ohm weerstand.

en de code van de bibliotheek maar die gebruik ik ook met andere projecten door middel van heel Veel shiftregisters en de shiftPWM lib en dan werkt het perfect!

#include"Arduino.h"



class OutputValue {
  public:
    OutputValue();
    void GoTo(uint8_t Channel, uint16_t FadeTime, uint8_t Value);
    void Playback(uint8_t PlaybackNum, uint16_t *Seq);
    void Refresh();
    uint8_t Output(uint8_t Channel);

  private:

    uint8_t _OV_NewValue[NUMBER_OF_OUTPUTS];
    uint8_t _OV_PrevValue[NUMBER_OF_OUTPUTS];
    uint16_t _OV_Arv[NUMBER_OF_OUTPUTS];
    int16_t _OV_Output[NUMBER_OF_OUTPUTS];
    uint16_t _OV_Speed[NUMBER_OF_OUTPUTS];
    
    uint8_t _OV_numChannels[NUM_PLAYBACK];
    uint8_t _OV_Step[NUM_PLAYBACK];
    uint32_t _OV_PrevMicros[NUMBER_OF_OUTPUTS];
    uint32_t _OV_PrevSeqMicros[NUM_PLAYBACK];


    uint32_t _OV_Micros;
};

OutputValue::OutputValue() {}

void OutputValue::GoTo(uint8_t Channel, uint16_t FadeTime, uint8_t Value) {
  if (Value != _OV_NewValue[Channel]) {
    _OV_PrevMicros[Channel] = _OV_Micros; // Set Micros
    _OV_PrevValue[Channel] = _OV_NewValue[Channel]; // Put newvalue into old value
    _OV_NewValue[Channel] = Value; // Get new value
    if (FadeTime != 0) { // IF fadetime != 0 run next code
      _OV_Arv[Channel] = FadeTime / abs(_OV_NewValue[Channel] - _OV_PrevValue[Channel]);
      //Arv = fadetime * 1000 / abs (Newvalue - old value)
      //SO:
      //Newvalue = 0, Old value = 255, fadetime = 1000 or 1 sec
      //0 - 255 = -255 Abs makes it Positive so 255
      //1000 * 1000 / 255 = 3921 Because i use millis 1000000 = 1 Sec now i can use 2 byte value instead of 4 bytes.
      // 3921 will be needed for the next function.
    } else {
      _OV_Arv[Channel] = 0;
    }
  }
}

void OutputValue::Playback(uint8_t PlaybackNum, uint16_t *Seq) {
  if (_OV_Micros - _OV_PrevSeqMicros[PlaybackNum] >= (uint32_t)_OV_Speed[PlaybackNum] * 1000 /*Seq[_OV_Step[PlaybackNum] * (Seq[0] + 1) * 2  + 2]*/) {
    _OV_PrevSeqMicros[PlaybackNum] = _OV_Micros;


    _OV_numChannels[PlaybackNum] = Seq[_OV_Step[PlaybackNum] * (_OV_numChannels[PlaybackNum] * 2 + 3) + 1];
    
    _OV_Speed[PlaybackNum] = Seq[_OV_Step[PlaybackNum] * (_OV_numChannels[PlaybackNum] * 2 + 3)  + 2];
    
    uint16_t fade = Seq[_OV_Step[PlaybackNum] * (_OV_numChannels[PlaybackNum] * 2 + 3)  + 3];

      /*Serial.print("Step : ");
      Serial.println(_OV_Step[PlaybackNum]);
      Serial.print("Amount : ");
      Serial.println(_OV_numChannels[PlaybackNum]);
      Serial.println(_OV_Speed[PlaybackNum]);
      Serial.println(fade); // speed */
      

    for (uint16_t Channel = 0; Channel < _OV_numChannels[PlaybackNum]; Channel++) {
      uint16_t OutputChannel;
      OutputChannel = Seq[_OV_Step[PlaybackNum] * (_OV_numChannels[PlaybackNum] * 2 + 3) + 4 + (Channel * 2)];
      _OV_PrevMicros[OutputChannel] = _OV_Micros;
      _OV_PrevValue[OutputChannel] = _OV_NewValue[OutputChannel];
      _OV_NewValue[OutputChannel] = Seq[_OV_Step[PlaybackNum] * (_OV_numChannels[PlaybackNum] * 2 + 3)  + 5 + (Channel * 2)];
      if (fade != 0) {
        _OV_Arv[OutputChannel] = ((uint32_t)fade * 1000) / abs(_OV_NewValue[OutputChannel] - _OV_PrevValue[OutputChannel]);
      } else {
        _OV_Arv[OutputChannel] = 0;
      }

      /*Serial.println(OutputChannel);
        Serial.println(_OV_PrevValue[OutputChannel]);
        Serial.println(_OV_NewValue[OutputChannel]);
        Serial.println(_OV_Arv[OutputChannel]);*/
    }
    if (_OV_Step[PlaybackNum] == Seq[0] - 1) { // Step++ or go back to Zero!
      _OV_Step[PlaybackNum] = 0;
    } else {
      _OV_Step[PlaybackNum]++;
    }

  }
}

void OutputValue::Refresh() {
  _OV_Micros = micros();
  for (uint16_t Channel = 0; Channel < NUMBER_OF_OUTPUTS; Channel++) { // go thru all the outputs.
    if (_OV_Arv[Channel] == 0) { // when Arv == 0 go to next value, NO fade!
      _OV_Output[Channel] = _OV_NewValue[Channel]; // go to next value no fade.
    } else {
      if (_OV_NewValue[Channel] > _OV_Output[Channel]) { // Yeah value is bigger lets Increase the output
        _OV_Output[Channel] = _OV_PrevValue[Channel] + (_OV_Micros - _OV_PrevMicros[Channel]) / _OV_Arv[Channel];
        // 255 + 500000 (0.5sec) - 0 / 3921 = 127.58 output
        //prev Value + micros - prevMicros / Arv
        // As you see after 0.5 sec the output value = halve way
      } else if (_OV_NewValue[Channel] < _OV_Output[Channel]) {//Yeah value is Smaller lets Decrease the output
        _OV_Output[Channel] = _OV_PrevValue[Channel] - (_OV_Micros - _OV_PrevMicros[Channel]) / _OV_Arv[Channel];
        // Same only then to decrease value.
      }
    }
    _OV_Output[Channel] = constrain(_OV_Output[Channel], 0, 255);
  }
}


inline uint8_t OutputValue::Output(uint8_t Channel) {
  return _OV_Output[Channel];
}

Uhmmm oke.

ik ben zelf uiteraard ook gaan googlen.
en ik kom op iets dat heet current leakage.

en voor me neus lag een 220 ohm weestand die ik effe op een PWM pin en ground heb gestoken en toen was het probleem weg!

ik kan ook de weerstand tussen een RGB pin en 5+ steken en dan is het probleem ook weg.

maar nu is er een nieuw probleem. als dit daadwerkelijk mijn probleem is heb ik geen idee wat voor weerstand ik nodig heb. hoe kan je dit berekenen?

door de matrix gaat er inderdaad nogal wat lekken, en dat kun je verminderen door op elke rgbpin een weerstand te zetten. jij kunt maar 1 led tegelijk sturen terwijl je er 8 tegelijk zou kunnen laten schijnen.
PWM en matrix heeft overigens weinig zin, dan kun je beter een scanner de helderheid laten regelen.

door de matrix gaat er inderdaad nogal wat lekken, en dat kun je verminderen door op elke rgbpin een weerstand te zetten.

maar hoe bereken je de weerstand die je nodig hebt?

jij kunt maar 1 led tegelijk sturen terwijl je er 8 tegelijk zou kunnen laten schijnen.

verklaar je nader.

ik kan idd maar 1 led sturen maar alle 12 heel snel achter elkaar. ik kan ze alle 12 zoals nu de situatie is laten schijnen/branden.
geen probleem werkt precies zo als ik wil.
gewoon 12 RGBleds met PWM functie. als de resolutie minder is maakt me niets zo veel uit. met het oog ziet het er prima uit.

PWM en matrix heeft overigens weinig zin, dan kun je beter een scanner de helderheid laten regelen.

tips? over de scanner waar je het over hebt. ik heb geen idee wat je precies bedoelt.

jij zet telkens maar 1 led aan, terwijl je ook een hele rij tegelijk kunt aanzetten, maar dan kun je geen PWM meer gebruiken, maar dan zet je dus een rij aan en zet ze uit als de teller op nul staat. (elke loop dan kijken of de teller al de pwm waarde heeft bereikt.
dat blauw meer problemen geeft is logisch door de hogere spanning die erover staat.
de weerstand kun je bepalen adhv de voedingsspanning de brandspanning en de spanning over de transistor etc.