Go Down

Topic: Fade optie voor NCS314 Arduino Shield Nixie Tube Clock (Read 317 times) previous topic - next topic

brutusss

Hallo Mede Arduino gebruikers,

Introductie:
Na een tijdje zoeken op internet ben ik dit forum tegen gekomen en ben benieuwd of iemand mij kan helpen met het implementeren van een extra optie in een bestaande firmware van mijn Nixie klok.



De firmware van de Gra & Afch IN-14 Arduino Shield Nixie tube Clock is vrij standaard zonder al te veel poespas.
Ik heb zelf met een vriend van me enkele opties toegevoegd zodat ik doormiddel van een ESPEasy de menu knoppen kan bedienen en de tubes kan uitschakelen.

Nu heeft iemand anders een fade optie gemaakt voor zijn Nixie Tubes en heb deze om zijn firmware gevraagd. De verschillen heb ik allemaal wel kunnen ontdekken in zijn firmware en kunnen plakken / verwerken in mijn eigen firmware. Als ik deze vervolgens toepas krijg ik geen fade in de overgang van de cijfers ze knipperen meer.

Ik heb wel een verschil in beide firmwares gevonden welke naar mijn mening zorgt voor dit probleem.
De NCS314 gebruikt de HV57708 64-Channel 32-MHz Serial-to-Parallel Converter with Push-Pull Outputs.
De NCT818 gebruikt de HV5122 32-Channel Serial-to-Parallel with Open-Drain Outputs.
In de arduino code wordt dit doormiddel van de SPI verschillend aangestuurd.

Knip uit de NCS314 doindication.ino firmware:
Code: [Select]
//-------- REG 1 -----------------------------------------------
  Var32=0;
 
  Var32|=(unsigned long)(SymbolArray[digits%10]&doEditBlink(5))<<20; // s2
  digits=digits/10;

  Var32|=(unsigned long)(SymbolArray[digits%10]&doEditBlink(4))<<10; //s1
  digits=digits/10;

  Var32|=(unsigned long)(SymbolArray[digits%10]&doEditBlink(3)); //m2
  digits=digits/10;

  if (LD) Var32|=LowerDotsMask;
    else  Var32&=~LowerDotsMask;
  
  if (UD) Var32|=UpperDotsMask;
    else Var32&=~UpperDotsMask;  

  for (int i=1; i<=32; i++)
  {
   i=i+32;
   int newindex=16*(3-(ceil((float)i/4)*4-i))+ceil((float)i/4);
   i=i-32;
   /*Serial.print("i=");
   Serial.print(i);
   Serial.print(" newindex=");
   Serial.println(newindex);*/
   if (newindex<=32) bitWrite(New32_L, newindex-1, bitRead(Var32, i-1));
    else bitWrite(New32_H, newindex-32-1, bitRead(Var32, i-1));
  }
 //-------------------------------------------------------------------------

 //-------- REG 0 -----------------------------------------------
  Var32=0;
  
  Var32|=(unsigned long)(SymbolArray[digits%10]&doEditBlink(2))<<20; // m1
  digits=digits/10;

  Var32|= (unsigned long)(SymbolArray[digits%10]&doEditBlink(1))<<10; //h2
  digits=digits/10;

  Var32|= (unsigned long)SymbolArray[digits%10]&doEditBlink(0); //h1
  digits=digits/10;

  if (LD) Var32|=LowerDotsMask;
    else  Var32&=~LowerDotsMask;
  
  if (UD) Var32|=UpperDotsMask;
    else Var32&=~UpperDotsMask;  

  for (int i=1; i<=32; i++)
  {
   int newindex=16*(3-(ceil((float)i/4)*4-i))+ceil((float)i/4);
   if (newindex<=32) bitWrite(New32_L, newindex-1, bitRead(Var32, i-1));
    else bitWrite(New32_H, newindex-32-1, bitRead(Var32, i-1));
  }

  SPI.transfer((New32_H)>>24);
  SPI.transfer((New32_H)>>16);
  SPI.transfer((New32_H)>>8);
  SPI.transfer(New32_H);
  
  SPI.transfer((New32_L)>>24);
  SPI.transfer((New32_L)>>16);
  SPI.transfer((New32_L)>>8);
  SPI.transfer(New32_L);

  digitalWrite(LEpin, HIGH); //<<-- это правильно H -> L
  digitalWrite(LEpin, LOW); // <<-- это правильно H -> L
//-------------------------------------------------------------------------


Knip uit de NCT818 doindication.ino firmware:
Code: [Select]
//-------- REG 1 -----------------------------------------------
  Var32=0;
 
  Var32|=(unsigned long)(SymbolArray[digits%10]&doEditBlink(5)&blankDigit(2))<<20; // s2
  digits=digits/10;

  Var32|=(unsigned long)(SymbolArray[digits%10]&doEditBlink(4)&blankDigit(3))<<10; //s1
  digits=digits/10;

  Var32|=(unsigned long) (SymbolArray[digits%10]&doEditBlink(3)&blankDigit(4)); //m2
  digits=digits/10;

  if (LD) Var32&=~LowerDotsMask;
    else  Var32|=LowerDotsMask;
  
  if (UD) Var32&=~UpperDotsMask;
    else  Var32|=UpperDotsMask;

  SPI.transfer(Var32>>24);
  SPI.transfer(Var32>>16);
  SPI.transfer(Var32>>8);
  SPI.transfer(Var32);

 //-------------------------------------------------------------------------

 //-------- REG 0 -----------------------------------------------
  Var32=0;
  
  Var32|=(unsigned long)(SymbolArray[digits%10]&doEditBlink(2)&blankDigit(5))<<20; // m1
  digits=digits/10;

  Var32|= (unsigned long)(SymbolArray[digits%10]&doEditBlink(1)&blankDigit(6))<<10; //h2
  digits=digits/10;

  Var32|= (unsigned long)SymbolArray[digits%10]&doEditBlink(0)&blankDigit(7); //h1
  digits=digits/10;

  if (LD) Var32&=~LowerDotsMask;  
    else  Var32|=LowerDotsMask;
  
  if (UD) Var32&=~UpperDotsMask;
    else  Var32|=UpperDotsMask;
    
  SPI.transfer(Var32>>24);
  SPI.transfer(Var32>>16);
  SPI.transfer(Var32>>8);
  SPI.transfer(Var32);
  if ((hour() < TimeToSleep) & (hour() >= TimeToWake))
//  if (!light)
  {
    digitalWrite(LEpin, HIGH);
  } else {    
    if ((counter2 % SleepDim) == 0) digitalWrite(LEpin, HIGH);  
  }
//-------------------------------------------------------------------------


Als ik de bovenstaande code van de NCT818 kopieer naar de NCS314 firmware is de Fade aanwezig alleen is er totaal geen logica meer naar welke tube wat gestuurd wordt. Kortom alles word door elkaar aangestuurd en er is totaal geen tijd af te lezen. Maar de gewenste fade is er wel :smiley-roll-blue: .

Eigen kennis:
Het betere knip en plak werk.

Firmwares Github:
Default Firmware NCS314
Modified Firmware NCT818

Schema:
Schema NCS314

Video's:
Fade optie toegevoegd zonder Registers aan te passen
Fade werkt met foute registers

Is het mogelijk dit toch goed werkend te krijgen? Ik hoop dat ik voldoende en duidelijke uitleg heb kunnen geven.

Alvast bedankt voor de gedane moeite!.

Met vriendelijke groet,
Brutus.

MAS3

Hoi brutusss, welkom !

Ik kan niet zeggen dat ik begrijp wat er in de snippets die je laat zien moet gebeuren.
Maar ik kan net zo goed als jij lezen wat daar staat, en dan valt dit verschil tussen de 2 snippets op:

Code: [Select]
  if (LD) Var32|=LowerDotsMask;
    else  Var32&=~LowerDotsMask;
 
  if (UD) Var32|=UpperDotsMask;
    else Var32&=~UpperDotsMask;


Tegen

Code: [Select]
  if (LD) Var32&=~LowerDotsMask;
    else  Var32|=LowerDotsMask;
 
  if (UD) Var32&=~UpperDotsMask;
    else  Var32|=UpperDotsMask;


Hier zie ik dat deze twee tegenovergesteld werken.

Verder is het in 90% (of meer) van de gevallen met zulke vragen, dat er bedradingsfouten zijn.
Nou is het natuurlijk zo dat je 1 van de 2 correct aan het werken hebt, maar je geeft ook aan dat er een hardware verschil zit in de 2 sketches.
Zo kan het zijn dat de ene converter een HIGH nodig heeft om een uitgang te activeren, en de andere een LOW.
En het kan zijn dat ze gewoon anders uitbedraad zijn (dus hoe de verbindingen tussen converter module en je nixie driver board lopen).
Dat uitbedraden moet jij dus met elkaar gaan vergelijken.
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

ArdLab_Gent

Begrijp je wat het verschil is tussen push-pull output en open-drain output?
op een push-pull output wordt door de driver spanning gezet, een open drain output is 1 enkele transistor waarvan de collector niet verbonden is en waar je zelf voor de spanning moet zorgen, beide outputs worden op een totaal andere manier geïntegreerd in het schema.

Heb je het schema van die klok?

ArdLab geeft Arduino workshops voor beginners.
ArdLab is lid van de STEM-Academie.
http://www.ardlab.gent - http://www.stem-academie.be/

brutusss

Dank voor jullie antwoorden!

@MAS3:
Dit zijn kant en klare shields welke je kan kopen. Het enige wat je hoeft te doen is de Arduino Uno of Mega te laden met een door hun aangeleverde standaard firmware.

Nu heb ik zelf met een vriend al enkele kleine aanpassingen gedaan aan deze standaard firmware om met een ESPEasy via domoticz de tubes uit en aan te kunnen zetten als ik niet thuis ben. Zo bespaar je de levensduur van de tubes een beetje. Nu had ik deze fade functie gezien en wilde deze graag implementeren maar er blijkt toch hardware verschillen te zijn waardoor de code ook anders is.

@ArdLab_Gent:
Ik begrijp dat er een verschil is tussen die twee outputs. Vandaar ook dat er een verschil zit in de output code. Ik begrijp alleen niet hoe ik dit zou moeten vertalen naar de firmware. De standaard firmware werkt uiteraard naar behoren hierin zou ik ook niks hoeven aanpassen. Ik zou alleen die fade opties willen toevoegen. Dat heb ik dus gedaan maar dat krijg ik niet aan de praat omdat de ene code gemaakt is voor de NCT818.  

Ik heb een link in de startpost gezet naar het schema van mijn Arduino shield.

Dit is wat die andere persoon heeft aangepast aan zijn firmware onder andere:
Code: [Select]
//driver for NCM107+NCT318+NCT818 (registers HV5122)
//driver version 1.0
//1 on register's output will turn on a digit

#include "doIndication818.h"

#define UpperDotsMask 0x80000000
#define LowerDotsMask 0x40000000

void doIndication()
{
  static unsigned long lastTimeInterval1Started;
  static unsigned long lastTimeInterval2Started;
//  int light = digitalRead(pinLightSens);
  static int fadecycles = 20;

  static int counter2 = 0;
  static int counter3 = 0;
  static int counter4 = fadecycles;
  static int fadebegin = 1;
  long digits=stringToDisplay.toInt();
  static int LastSecond = second();
  if ((micros()-lastTimeInterval1Started)<fpsLimit) return;

if (LastSecond == second()) {
  counter2 ++;
  counter3 ++;
} else {
  counter2 = 0;
  counter3 = 0;
  counter4 = fadecycles;
  fadebegin = 1;
  LastSecond = second();
  lastTimeInterval2Started=micros();
}
  //if (menuPosition==TimeIndex) doDotBlink();
  lastTimeInterval1Started=micros();
  unsigned long Var32=0;
  if (
      (counter2 < 300)
    & (menuPosition == TimeIndex)
    & (second() > 0)
    & ((micros()-lastTimeInterval2Started) > 100)
//    & (!light)
    & (hour() < TimeToSleep)
    & (hour() >= TimeToWake)
    & !transactionInProgress
      )
    {
      if (fadebegin == 1) {
        if (((counter3) <= counter4))
        {
      digits = prevstringToDisplay.toInt();
    } else {
      counter4 --;
      counter3 = 0;
      digits=stringToDisplay.toInt();  
      }
      if (counter4 <= 2) {
        fadebegin = 0;
        counter4 = 0;
        counter3 = 0;
        }
    } else {
    if (((counter3) <= counter4)) {
      digits = stringToDisplay.toInt();
      } else {
        counter4 ++;
        counter3 = 0;
        digits = prevstringToDisplay.toInt();
        }
      }
    } else digits=stringToDisplay.toInt();
 
  //long digits=stringToDisplay.toInt();
  //long digits=12345678;
  //Serial.print("strtoD=");
  //Serial.println(stringToDisplay);
  
  /**********************************************************
   * Подготавливаем данные по 32бита 3 раза
   * Формат данных [H1][H2}[M1][M2][S1][Y1][Y2]
   *********************************************************/
  
  digitalWrite(LEpin, LOW);

 
 //-------- REG 1 -----------------------------------------------


Hierna komt het hierboven al eerder genoteerde code van de registers.

Met vriendelijke groet,
Brutus.

shooter

als de fade begint moet je de timer wel op nul zetten net zoals aan het eind een andere timer, dat zie ik niet,
paul deelen
shooter@home.nl
making controls with codesys PLC and arduino

brutusss

als de fade begint moet je de timer wel op nul zetten net zoals aan het eind een andere timer, dat zie ik niet,

Dank voor je antwoord, zou je me wellicht kunnen aangeven wat ik waar zou moeten toevoegen? 

brutusss

Zojuist enkele video's toegevoegd aan de start post welke visueel aangeven wat er gebeurd met de verschillende codes.

Tubes werken normaal op de NCS314 alleen de fade hapert: Video
Tubes werken niet normaal maar de fade wel NCS314 firmware met de register codes van de NCT818: Video

jvs68

Hallo Brutuss, volgens mij zijn we elkaar op het Gra&Afch forum tegengekomen gisteren. De code die je linkte werkt idd min of meer, er is een fade-in maar geen fade-out. Maar in elk geval snap ik het principe nu en daar kan ik wel op voortbouwen.

Wat betreft jouw probleem met de random digits, ik zie dat ze in de firmware voor jouw 64 channel driver 2 for-loops ingebakken hebben die ik niet heb met mijn 2x32 channel drivers:

Code: [Select]
for (int i=1; i<=32; i++)
 {
  i=i+32;
  int newindex=16*(3-(ceil((float)i/4)*4-i))+ceil((float)i/4);
  i=i-32;
  /*Serial.print("i=");
  Serial.print(i);
  Serial.print(" newindex=");
  Serial.println(newindex);*/
  if (newindex<=32) bitWrite(New32_L, newindex-1, bitRead(Var32, i-1));
   else bitWrite(New32_H, newindex-32-1, bitRead(Var32, i-1));
 }


en

Code: [Select]
 for (int i=1; i<=32; i++)
 {
  int newindex=16*(3-(ceil((float)i/4)*4-i))+ceil((float)i/4);
  if (newindex<=32) bitWrite(New32_L, newindex-1, bitRead(Var32, i-1));
   else bitWrite(New32_H, newindex-32-1, bitRead(Var32, i-1));
 }


Deze 2 loopjes lijken de bitstream om te catten naar iets dat de 64 channel driver nodig heeft. Heb je deze loopjes veranderd foen je de fade probeerde aan het werkt te krijgen?

Als je het niet kunt vinden zou ik bij de 2 versies die je nu hebt (met en zonder fade) mbv serial print de bit patronen vergelijken die naar de chip gestuurd worden om het verschiil tussen 'voor' en 'na' te achterhalen. Als ik het zo hooghover bekijk zou ik verwachten dat zolang je niet aan die for-loops komt, en alleen de code van Vasques op de juiste plek er tussen plakt, je geen verschil zou mogen krijgen in welke nummers van je Nixie aangaan.

Johan


brutusss

He Johan,

Klopt dat was ik. Blij dat ik je een zetje in de goede richting heb kunnen geven! ;)

Die twee stukken code zijn er inderdaad extra bijgezet om de 64bit driver aan te kunnen sturen. Op jou vraag:

"Deze 2 loopjes lijken de bitstream om te catten naar iets dat de 64 channel driver nodig heeft. Heb je deze loopjes veranderd foen je de fade probeerde aan het werkt te krijgen?"

Ja en nee. Ik heb alleen de code welke boven de registers zitten toegevoegd welke zorgen voor de fade. De code welke jij ook benoemd heb mag ik naar mijn mening niet aanpassen omdat dit juist ervoor zorgt dat mijn driver goed werkt met de bestaande code.

Maar om te testen wat het zou doen als ik de gehele code zou toevoegen kreeg ik dus een goede fade maar random digits. Dus om het samen te vatten:
- Als ik de gehele code van de NCT818 laad dan krijg ik dus 32 bits aansturing met goede fade en random digits.
- Als ik alleen de fade code kopieer krijg ik dus die haperingen maar wel de juiste digits.

Jou code en die van de NCT818 heeft ook alleen maar een:
Code: [Select]
SPI.transfer(Var32>>24);
 SPI.transfer(Var32>>16);
 SPI.transfer(Var32>>8);
 SPI.transfer(Var32);

Terwijl die van mij vertaald word naar twee verschillende:
Code: [Select]
SPI.transfer((New32_H)>>24);
 SPI.transfer((New32_H)>>16);
 SPI.transfer((New32_H)>>8);
 SPI.transfer(New32_H);
  
 SPI.transfer((New32_L)>>24);
 SPI.transfer((New32_L)>>16);
 SPI.transfer((New32_L)>>8);
 SPI.transfer(New32_L);

 
Wat uiteraard ook te zien is in de code welke jij al aangaf.

Als ik de Serial Monitor aanzet met mijn aangepast versie valt me het volgende op:
Code: [Select]
Serial.println(stringToDisplay);
Start Test
000000
000000
111111
111111
222222
222222

Zichtbaar is alleen: 0 --> 2 --> 0 --> 4 --> 0 enz.
Terwijl het moet zijn: 0 --> 1 --> 2 --> 3 enz.

Vervolgens word ongeveer per seconde 112 keer dezelfde tijd verstuurd: 230154

In de standaard firmware zie ik geen "serial.print" staan welke dezelfde output kan geven als hierboven.

In de bijlage heb ik mijn aangepaste versie geplaatst welke ik naar mijn mening voorzien heb van de juiste "Fade" code. Wellicht zou je hier iets aan kunnen zien.

De firmware welke is bijgevoegd geeft dit resultaat.

Bedankt voor je hulp tot nu toe!

Groeten Brutus.

jvs68

Brutus,

Dat probleem van --> 2 --> 0 --> 4 kan ik meteen voor je oplossen,. Dat had ik ook namelijk.

Eigenlijk is de test run een speciale procedure, net zoals het af en toe de datum laten zien en de anti-poisoning cycle. Tijdens die speciale procedures moet de fade uitgeschakeld zijn. Voor die andere procedures wordt dit opgelost door de flag 'transactionInProgress' te zetten. Als je dat ook doet voor de test procedure dan loopt dat allemaal weer smooth. 

Dus in de main code file even zoeken naar de doTest() procedure en dan toevoegen als eerste regel:


Code: [Select]
transactionInProgress = true;


en laatste regel:


Code: [Select]
transactionInProgress = false;

Wat betreft de hapering, ik zal vanavond in iets meer detail kijken maar klinkt als een timing probleem. Het idee achter de fade is dat 1 op de zoveel 'frames/second' het nieuwe getal laat zien den de rest van de frames de oude. Ik moet de code van Vasques nog goed uitpluizen (werkt bij mij ook niet zo smooth als ik zou willen) maar volgens mij is het 1 op de 20 frames (gecontroleerd door de fadecycles variabele).

Omdat jij ook nog die for loop in je code hebt staan, die natuurlijk ook flink cpu cycles kost, vermoed ik dat het nieuwe nummer gewoon niet vaak genoeg doorgestuurd wordt enm daarom gaat knipperen. Ik zou als eerste eens proberen om 'fadecycles' te initialiseren op 10 ipv 20 en anders je overall fpslimit te verlagen van 1000 naar 500 bv. Kijken of het dan beter wordt en vervolgens de optimale waarden zoeken dmv trial & error...

Johan



brutusss

He Johan,

Het toevoegen van die code over de doTest() heen heeft dat probleem inderdaad verholpen. Top!

Het aanpassen van die waardes geeft zeker een zichtbaar verschil. Het is nu meer een strobe effect. Hieronder mijn bevindingen:
fadecycles = 10 en fpslimit 500 --> Stoboscoop effect. fpslimit 100 tot 3000 of hoger weinig verschil.
fadecycles = 30 en fpslimit 500 --> Knipper effect heel langzaam. fpslimit naar 1000 maakt geen zichtbaar verschil.

Het helpt dus iets maar het maakt het niet smooth zeg maar.

Wederom bedankt!

Groeten Brutus.

jvs68

Brutus,

Misschien heb je er wat aan, ik heb even een test-sketch gemaakt om makkelijker de fades uit te kunnen proberen:

Code: [Select]
#include <SPI.h>

const byte LEpin = 10;                                              //pin Latch Enabled data accepted while HI level
SPISettings settingsA(8000000, MSBFIRST, SPI_MODE2);                //SPI setup for HV5122PJ

String stringToDisplay;                                             // Content of this string will be displayed on tubes (must be 6 chars length)
String prevstringToDisplay;                                         // Content of the previous string for fading purposes

unsigned int SymbolArray[10] = {1,     2,     4,     8,     16,    32,    64,    128,   256,    512}; // used to translate number (0-9) to bit pattern


/*******************************************************************************************************
  Init Programm
*******************************************************************************************************/
void setup()
{

  Serial.begin(115200);
  Serial.println(F("Starting"));

  //Setup SPI communication, see https://www.arduino.cc/en/Tutorial/SPITransaction for example & documentation

  pinMode(LEpin, OUTPUT);
  SPI.begin();
  SPI.beginTransaction(settingsA);
}

/***************************************************************************************************************
  MAIN Programm
***************************************************************************************************************/
void loop() {
  static int i = 1;
  prevstringToDisplay = String("000000");
  do {
    if (i < 10) {
      stringToDisplay = String("00000") + String(i);
    } else if (i < 100) {
      stringToDisplay = String("0000") + String(i);
    } else if (i < 1000) {
      stringToDisplay = String("000") + String(i);
    } else if (i < 10000) {
      stringToDisplay = String("00") + String(i);
    } else if (i < 100000) {
      stringToDisplay = String("0") + String(i);
    }
    doIndication();
    i++;
    prevstringToDisplay = stringToDisplay;
  } while (i < 999999);
}

void doIndication()
{
  static unsigned long fadeDuration = 1000; //how long should fade last, in milliseconds. Initialize at second but you can play with this
  static unsigned long fadeEndTime;         //hold current point that the fade needs to end in milliseconds
  static int           minFadeCycle;        //the minimum number of times new digit should be activated ie. 20 means 1 in 20 cycles is new digit
  static int           currentFadeCycle;    //we want to progressively make new digit brighter so cycles need to go up. Will go progressively from minFadeCycle to every time
  static int           fadeFrameCounter;    //keep track of when we last displayed the new frame

  long digits;                              //used in translation of stringtodisplay to bitpattern
  unsigned long var32_L = 0;                //Will hold 2nd 32 bits to send over
  unsigned long var32_H = 0;                //Will hold 1st 32 bits to sned over

  // Initialize our variables
  minFadeCycle = 30;                        //Initiate at 1:30, can play with this
  fadeFrameCounter = 0;                     //just beginning
  fadeEndTime = millis() + fadeDuration;    //keep track of when fade needs to be finished

  do {
    currentFadeCycle = ((float)(fadeEndTime - millis()) / (float)fadeDuration) * (float)minFadeCycle;  // where are we relative to start of fade. The further progressed the more often we display new number
    if (fadeFrameCounter >= currentFadeCycle) {      //do we need to show new digit?
      digits = stringToDisplay.toInt();
      fadeFrameCounter = 0;                          //rinse & repeat
    } else {
      digits = prevstringToDisplay.toInt();          //not yet, show old digit
    }

    //Serial.println(digits);
    //--Reg1--
    var32_H = 0;
    var32_H |= (unsigned long)(SymbolArray[digits % 10]) << 20; // s2
    digits = digits / 10;
    var32_H |= (unsigned long)(SymbolArray[digits % 10]) << 10; //s1
    digits = digits / 10;
    var32_H |= (unsigned long)(SymbolArray[digits % 10]); //m2
    digits = digits / 10;

    //--Reg0--
    var32_L = 0;
    var32_L |= (unsigned long)(SymbolArray[digits % 10]) << 20; // m1
    digits = digits / 10;
    var32_L |= (unsigned long)(SymbolArray[digits % 10]) << 10; //h2
    digits = digits / 10;
    var32_L |= (unsigned long)SymbolArray[digits % 10]; //h1
    digits = digits / 10;

    digitalWrite(LEpin, LOW);
    SPI.transfer(var32_H >> 24);
    SPI.transfer(var32_H >> 16);
    SPI.transfer(var32_H >> 8);
    SPI.transfer(var32_H);

    SPI.transfer(var32_L >> 24);
    SPI.transfer(var32_L >> 16);
    SPI.transfer(var32_L >> 8);
    SPI.transfer(var32_L);

    digitalWrite(LEpin, HIGH);

    fadeFrameCounter++;                                 //up the framecounter
  } while (millis() < fadeEndTime);
}


Ik denk ook uiteindelijk een handiger manier dan diue van Vasques om dit uiteindelijk goed werkend te krijgen en ook met wat helderder kommentaar erin. Het is een simpele teller die op 0 begint en elke digit erin 'fade'. Staat op 1 seconde fadetijd nu maar kun je ook langzamer of sneller maken.

Deze zou voor jou ook moeten werken, alleen moet je wat verstuurd wordt omschrijven voor jouw 64 channel chip. Oh ook belangrijk aandachtspunt, ik heb de SPI initialisatie gemoderniseerd (in mijn firmware werden nog oude calls gebruikt), voor jou bord is de initialisatie iets anders volgens mij. Nl:


Code: [Select]
SPISettings settingsA(1000000, MSBFIRST, SPI_MODE3);
SPI.begin();
SPI.beginTransaction(settingsA);


(en dan op de juiste plekken in de code);

Kiek moar of je er wat aan hebt.



brutusss

He Johan,

Dat ziet er netjes uit! Ik ben aan de slag gegaan en heb hem meteen eens ingeladen maar dan krijg ik niks te zien.
Ik heb hem vervolgens aangepast met de Reg 1 en 0 van mijn board maar ook dan gaat niks aan.

Code: [Select]
#include <SPI.h>

const byte LEpin = 10;                                              //pin Latch Enabled data accepted while HI level
SPISettings settingsA(8000000, MSBFIRST, SPI_MODE3);                //SPI setup for HV5122PJ

String stringToDisplay;                                             // Content of this string will be displayed on tubes (must be 6 chars length)
String prevstringToDisplay;                                         // Content of the previous string for fading purposes

unsigned int SymbolArray[10] = {1,     2,     4,     8,     16,    32,    64,    128,   256,    512}; // used to translate number (0-9) to bit pattern


/*******************************************************************************************************
  Init Programm
*******************************************************************************************************/
void setup()
{

  Serial.begin(115200);
  Serial.println(F("Starting"));

  //Setup SPI communication, see https://www.arduino.cc/en/Tutorial/SPITransaction for example & documentation

  pinMode(LEpin, OUTPUT);
  SPI.begin();
  SPI.beginTransaction(settingsA);
}

/***************************************************************************************************************
  MAIN Programm
***************************************************************************************************************/
void loop() {
  static int i = 1;
  prevstringToDisplay = String("000000");
  do {
    if (i < 10) {
      stringToDisplay = String("00000") + String(i);
    } else if (i < 100) {
      stringToDisplay = String("0000") + String(i);
    } else if (i < 1000) {
      stringToDisplay = String("000") + String(i);
    } else if (i < 10000) {
      stringToDisplay = String("00") + String(i);
    } else if (i < 100000) {
      stringToDisplay = String("0") + String(i);
    }
    doIndication();
    i++;
    prevstringToDisplay = stringToDisplay;
  } while (i < 999999);
}

void doIndication()
{
  static unsigned long fadeDuration = 1000; //how long should fade last, in milliseconds. Initialize at second but you can play with this
  static unsigned long fadeEndTime;         //hold current point that the fade needs to end in milliseconds
  static int           minFadeCycle;        //the minimum number of times new digit should be activated ie. 20 means 1 in 20 cycles is new digit
  static int           currentFadeCycle;    //we want to progressively make new digit brighter so cycles need to go up. Will go progressively from minFadeCycle to every time
  static int           fadeFrameCounter;    //keep track of when we last displayed the new frame

  long digits;                              //used in translation of stringtodisplay to bitpattern
  unsigned long Var32=0;
  unsigned long New32_L=0;                  //Will hold 2nd 32 bits to send over
  unsigned long New32_H=0;                  //Will hold 1st 32 bits to sned over

  // Initialize our variables
  minFadeCycle = 30;                        //Initiate at 1:30, can play with this
  fadeFrameCounter = 0;                     //just beginning
  fadeEndTime = millis() + fadeDuration;    //keep track of when fade needs to be finished

  do {
    currentFadeCycle = ((float)(fadeEndTime - millis()) / (float)fadeDuration) * (float)minFadeCycle;  // where are we relative to start of fade. The further progressed the more often we display new number
    if (fadeFrameCounter >= currentFadeCycle) {      //do we need to show new digit?
      digits = stringToDisplay.toInt();
      fadeFrameCounter = 0;                          //rinse & repeat
    } else {
      digits = prevstringToDisplay.toInt();          //not yet, show old digit
    }

    Serial.println(digits);
   
    //--Reg1--
  Var32=0;
 
  Var32|=(unsigned long)(SymbolArray[digits%10])<<20; // s2
  digits=digits/10;
  Var32|=(unsigned long)(SymbolArray[digits%10])<<10; //s1
  digits=digits/10;
  Var32|=(unsigned long)(SymbolArray[digits%10]); //m2
  digits=digits/10;
 
  for (int i=1; i<=32; i++)
  {
   i=i+32;
   int newindex=16*(3-(ceil((float)i/4)*4-i))+ceil((float)i/4);
   i=i-32;
   /*Serial.print("i=");
   Serial.print(i);
   Serial.print(" newindex=");
   Serial.println(newindex);*/
   if (newindex<=32) bitWrite(New32_L, newindex-1, bitRead(Var32, i-1));
    else bitWrite(New32_H, newindex-32-1, bitRead(Var32, i-1));
  }

    //--Reg0--
  Var32=0;
 
  Var32|=(unsigned long)(SymbolArray[digits%10])<<20; // m1
  digits=digits/10;
  Var32|= (unsigned long)(SymbolArray[digits%10])<<10; //h2
  digits=digits/10;
  Var32|= (unsigned long)SymbolArray[digits%10]; //h1
  digits=digits/10;

  for (int i=1; i<=32; i++)
  {
   int newindex=16*(3-(ceil((float)i/4)*4-i))+ceil((float)i/4);
   if (newindex<=32) bitWrite(New32_L, newindex-1, bitRead(Var32, i-1));
    else bitWrite(New32_H, newindex-32-1, bitRead(Var32, i-1));
  }

  SPI.transfer((New32_H)>>24);
  SPI.transfer((New32_H)>>16);
  SPI.transfer((New32_H)>>8);
  SPI.transfer(New32_H);
 
  SPI.transfer((New32_L)>>24);
  SPI.transfer((New32_L)>>16);
  SPI.transfer((New32_L)>>8);
  SPI.transfer(New32_L);

  digitalWrite(LEpin, HIGH); //<<-- это правильно H -> L
  digitalWrite(LEpin, LOW); // <<-- это правильно H -> L

    fadeFrameCounter++;                                 //up the framecounter
  } while (millis() < fadeEndTime);
}


Zie hier de code die ik ervan gemaakt heb. Op de serial monitor zie ik hem inderdaad netjes optellen.
Zou dit op alle tubes tegelijk zichtbaar moeten zijn? Lopen ze bij jou nu wel netjes?

Betreft die SPI modes heb ik eigenlijk dan alleen maar de MODE op 3 moeten zetten.

Wat doe ik fout ::)?

Groeten Michaël.

jvs68

Brutus,

HJij telt bij mij netjes op idd (met fade effect :-)).

Even op het eerste gezicht:

In jouw originele firmware zijn de SPI Settings (1000000, MSBFIRST, SPI_MODE3). In jouw code staat er 8000000 ipv 1000000. Daar zou het in kunnen zitten.

Daarnaast vind ik het raar hoe zij LEpin hoog en laag zetten. Dat zou ik liever als volgt doen:


Code: [Select]
  digitalWrite(LEpin, LOW);
  SPI.transfer((New32_H)>>24);
  SPI.transfer((New32_H)>>16);
  SPI.transfer((New32_H)>>8);
  SPI.transfer(New32_H);
 
  SPI.transfer((New32_L)>>24);
  SPI.transfer((New32_L)>>16);
  SPI.transfer((New32_L)>>8);
  SPI.transfer(New32_L);
  digitalWrite(LEpin, HIGH);


Eens kijken of het daar beter van wordt?

brutusss

Johan,

Ik ben jaloers.. Ik zou graag willen dat hij dat bij mij ook deed haha :D.

Ik heb de code aangepast maar er gebeurt helemaal niks. Ik hoef toch letterlijk alleen maar de onderstaande code in te laden? Zonder enige andere file welke ernaast staat zoals met de originele firmware? Mij lijkt van niet aangezien ik zie dat je diverse benodigde code ook al uit andere files gehaald hebt.

Met jou code standaard code zou ik toch op zijn minst random dingen moeten krijgen.. Hieronder de code met je aanwijzigingen:
Code: [Select]

#include <SPI.h>

const byte LEpin = 10;                                              //pin Latch Enabled data accepted while HI level
SPISettings settingsA(1000000, MSBFIRST, SPI_MODE3);                //SPI setup for HV5122PJ

String stringToDisplay;                                             // Content of this string will be displayed on tubes (must be 6 chars length)
String prevstringToDisplay;                                         // Content of the previous string for fading purposes

unsigned int SymbolArray[10] = {1,     2,     4,     8,     16,    32,    64,    128,   256,    512}; // used to translate number (0-9) to bit pattern


/*******************************************************************************************************
  Init Programm
*******************************************************************************************************/
void setup()
{

  Serial.begin(115200);
  Serial.println(F("Starting"));

  //Setup SPI communication, see https://www.arduino.cc/en/Tutorial/SPITransaction for example & documentation

  pinMode(LEpin, OUTPUT);
  SPI.begin();
  SPI.beginTransaction(settingsA);
}

/***************************************************************************************************************
  MAIN Programm
***************************************************************************************************************/
void loop() {
  static int i = 1;
  prevstringToDisplay = String("000000");
  do {
    if (i < 10) {
      stringToDisplay = String("00000") + String(i);
    } else if (i < 100) {
      stringToDisplay = String("0000") + String(i);
    } else if (i < 1000) {
      stringToDisplay = String("000") + String(i);
    } else if (i < 10000) {
      stringToDisplay = String("00") + String(i);
    } else if (i < 100000) {
      stringToDisplay = String("0") + String(i);
    }
    doIndication();
    i++;
    prevstringToDisplay = stringToDisplay;
  } while (i < 999999);
}

void doIndication()
{
  static unsigned long fadeDuration = 1000; //how long should fade last, in milliseconds. Initialize at second but you can play with this
  static unsigned long fadeEndTime;         //hold current point that the fade needs to end in milliseconds
  static int           minFadeCycle;        //the minimum number of times new digit should be activated ie. 20 means 1 in 20 cycles is new digit
  static int           currentFadeCycle;    //we want to progressively make new digit brighter so cycles need to go up. Will go progressively from minFadeCycle to every time
  static int           fadeFrameCounter;    //keep track of when we last displayed the new frame

  long digits;                              //used in translation of stringtodisplay to bitpattern
  unsigned long Var32=0;
  unsigned long New32_L=0;                  //Will hold 2nd 32 bits to send over
  unsigned long New32_H=0;                  //Will hold 1st 32 bits to sned over

  // Initialize our variables
  minFadeCycle = 30;                        //Initiate at 1:30, can play with this
  fadeFrameCounter = 0;                     //just beginning
  fadeEndTime = millis() + fadeDuration;    //keep track of when fade needs to be finished

  do {
    currentFadeCycle = ((float)(fadeEndTime - millis()) / (float)fadeDuration) * (float)minFadeCycle;  // where are we relative to start of fade. The further progressed the more often we display new number
    if (fadeFrameCounter >= currentFadeCycle) {      //do we need to show new digit?
      digits = stringToDisplay.toInt();
      fadeFrameCounter = 0;                          //rinse & repeat
    } else {
      digits = prevstringToDisplay.toInt();          //not yet, show old digit
    }

    Serial.println(digits);
  
    //--Reg1--
  Var32=0;
 
  Var32|=(unsigned long)(SymbolArray[digits%10])<<20; // s2
  digits=digits/10;
  Var32|=(unsigned long)(SymbolArray[digits%10])<<10; //s1
  digits=digits/10;
  Var32|=(unsigned long)(SymbolArray[digits%10]); //m2
  digits=digits/10;
 
  for (int i=1; i<=32; i++)
  {
   i=i+32;
   int newindex=16*(3-(ceil((float)i/4)*4-i))+ceil((float)i/4);
   i=i-32;
   /*Serial.print("i=");
   Serial.print(i);
   Serial.print(" newindex=");
   Serial.println(newindex);*/
   if (newindex<=32) bitWrite(New32_L, newindex-1, bitRead(Var32, i-1));
    else bitWrite(New32_H, newindex-32-1, bitRead(Var32, i-1));
  }

    //--Reg0--
  Var32=0;
 
  Var32|=(unsigned long)(SymbolArray[digits%10])<<20; // m1
  digits=digits/10;
  Var32|= (unsigned long)(SymbolArray[digits%10])<<10; //h2
  digits=digits/10;
  Var32|= (unsigned long)SymbolArray[digits%10]; //h1
  digits=digits/10;

  for (int i=1; i<=32; i++)
  {
   int newindex=16*(3-(ceil((float)i/4)*4-i))+ceil((float)i/4);
   if (newindex<=32) bitWrite(New32_L, newindex-1, bitRead(Var32, i-1));
    else bitWrite(New32_H, newindex-32-1, bitRead(Var32, i-1));
  }

  digitalWrite(LEpin, LOW);
  SPI.transfer((New32_H)>>24);
  SPI.transfer((New32_H)>>16);
  SPI.transfer((New32_H)>>8);
  SPI.transfer(New32_H);
 
  SPI.transfer((New32_L)>>24);
  SPI.transfer((New32_L)>>16);
  SPI.transfer((New32_L)>>8);
  SPI.transfer(New32_L);
  digitalWrite(LEpin, HIGH);

    fadeFrameCounter++;                                 //up the framecounter
  } while (millis() < fadeEndTime);
}


Heeft deze wellicht nog enige invloed? Ik zie dit eigenlijk nergens terug komen in de originele firmware.
Code: [Select]
pinMode(LEpin, OUTPUT);

Wederom bedankt! Ik waardeer het zeer dat je me wil helpen.

Groeten Brutus.

Go Up