Forum Électro-Bidouilleur

Merci de vous connecter ou de vous inscrire.

Connexion avec identifiant, mot de passe et durée de la session
Recherche avancée  

Nouvelles:

Le Forum est maintenant chiffré (préambule https). Bien sûr, des liens externes insérés dans les sujets vont demeurer inchangés. Mais la composition des pages du Forum est désormais sécurisée. Si des problèmes d'affichage surviennent, veillez à vider votre cache pour ce site.

Voir les contributions

Cette section vous permet de consulter les contributions (messages, sujets et fichiers joints) d'un utilisateur. Vous ne pourrez voir que les contributions des zones auxquelles vous avez accès.

Messages - cyberfun

Pages: [1]
1
Bonjour Bidouilleurs et bidouilleuses...
En avant pour une nouvelle année 2020, Bonne et heureuse année avec tout ce qui va avec...

Piloter un ADC en mode directe sa avance pas mal de choses et l'on obtient une vitesse plus rapide car le code est optimisé ! J'avais deja eu l'idée de le programmer de la sorte... Après visu sur le forum arduino.cc du sujet quelqu'un avait déjà  codé l'histoire....
Exemple en dessous pour ceux qui ont vu le post forum du sujet en question sur arduino.cc

140khz en moyenne qui augmente par rapport au 8khz au code standard super la performance mais dessiner une grille ou une syncro... j'y suis pas encore arrivé je fais cela a mes moments perdu de la semaine... Il faut analysé l'echantillonnage stocké et... ben je pedale dans la semoule...

Enfin l'idée est excéllente, quelqu'un d'autre a trouvé quelques choses de plus précis ?

#include <TVout.h>
#include <font4x6.h>

//input pins
const int scalePin = 2;
const int samplePin = 3;
// analog input pin is fixed to 0

// define the graph area
const int graphOffsetX = 18;
const int graphOffsetY = 94;
const int graphWidth = 100;
const int graphHeight = 86;

const int upperGraphLimit = graphOffsetY + 1;
const int lowerGraphLimit = graphOffsetY - graphHeight;

int scaleFactor = 1024/graphHeight+1;
int offset = 0;
int sampleSize = -4;
// if sampleSize <= 0, it denotes the sampling speed.

int minValue, maxValue, avgValue;
long startTime = 0, sampleTime = 0;

//used if sampleSize <=3 to draw faster
int data[graphWidth];
uint8_t dispY[graphWidth];

TVout TV;

void setup(){                                         
  pinMode(scalePin, INPUT_PULLUP);     
  pinMode(samplePin, INPUT_PULLUP);     

  //init TV
  TV.begin(_NTSC,120,96);
  TV.select_font(font4x6);
 
  clearGraph();
  drawScale();
}

void initADC(int speed){
  // speed == 1: normal analogread.
  // speed in [-4,0]: faster (-4 is the fastest)

  ADCSRA = 0x87; //default
  if ( speed >= 1 ) ADCSRA = 0x87;    // turn on adc, freq  = 1/128,  125 kHz.
  if ( speed == 0 ) ADCSRA = 0x86;    // turn on adc, freq  = 1/64,   250 kHz.
  if ( speed == -1 ) ADCSRA = 0x85;   // turn on adc, freq  = 1/32,   500 kHz.
  if ( speed == -2 ) ADCSRA = 0x84;   // turn on adc, freq  = 1/16 ,    1 MHz.
  if ( speed == -3 ) ADCSRA = 0x83;   // turn on adc, freq  = 1/8,      2 MHz.
  if ( speed == -4 ) ADCSRA = 0x82;   // turn on adc, freq  = 1/4,      4 MHz. 

  ADMUX = 0x40;
  ADCSRA |= (1<<ADSC);
  while(!(ADCSRA & 0x10));
}

void resetADC(){
  ADCSRA = 0x00;
}

void readFast(int speed){
  // fills array with data on analog-pin 0.
  // speed >= 1: sample "speed" times and take the adverage.
  // speed in [-4,0]: read faster (-4 is the fastest)
 
  int * data_ptr = data; // pointer to array
 
  volatile char i = graphWidth; // iterator in array, init with array size
  volatile int val = 0, sum;
 
  initADC(speed);
 
  startTime = micros(); // set startTime here, to get a more accurate rate
  if(speed > 1){
    ADCSRA |= (1<<ADSC); // start reading the first value
    do{
      sum = 0;
      for(int j=0; j<speed; j++){
        while(!(ADCSRA & 0x10)); // wait for output
        val = ADCL;  // read out low data bits
        val += (ADCH << 8); // read out high data bits
        ADCSRA |= (1<<ADSC); // already start reading the next value for more speed
        sum += val;
      }
      *data_ptr++ = sum / speed;
    }while(--i);
  }else{
    ADCSRA |= (1<<ADSC); // start reading the first value
    do{
      while(!(ADCSRA & 0x10));
      val = ADCL;
      val += (ADCH << 8);
      ADCSRA |= (1<<ADSC); // already start reading the next value for more speed
      *data_ptr++ = val;
    }while(--i);
  }
  resetADC();
}

void waitFor(int speed, int threshold){
  volatile int val = 0;

  initADC(speed);

  boolean wasLow = false;
  ADCSRA |= (1<<ADSC); // start reading first value
  for(int w=0 ; w<400 ; w++){
    while(!(ADCSRA & 0x10));
    val = ADCL;
    val += (ADCH << 8);
    ADCSRA |= (1<<ADSC); // already start reading next value for more speed
    if(val < threshold){
      wasLow = true;
    }else if((val > threshold) && wasLow){
      break;
    }
  }
  resetADC();
}

void drawPixel(int x, int y, char c){
  if((y > lowerGraphLimit) && (y < upperGraphLimit)){
    TV.set_pixel(x,y,c);
  }
}

int val2y(int val){
  return graphOffsetY - val/scaleFactor - offset;
}

void drawScale(){
  //delete old scale
  TV.draw_rect(0,lowerGraphLimit, graphOffsetX-2,graphHeight+1,0,0);
 
  for(int i = 0; i<=20;i++){
    int y = val2y(1024 * i / 20);
    drawPixel(graphOffsetX-2,y,1);
    if((i % 2 != 0) && (scaleFactor < 8) && (y > lowerGraphLimit + 3) && (y < upperGraphLimit - 3)){
      TV.print(graphOffsetX - 18,y-3,i/4.0,2);
    }
    if(i % 2 == 0){
      drawPixel(graphOffsetX-3,y,1); 
      if((i % 4 != 0) && (scaleFactor <=8) && (y > lowerGraphLimit + 3) && (y < upperGraphLimit - 3)){
        TV.print(graphOffsetX - 15,y-3,i/4.0,1);
      }
    }
    if(i % 4 == 0){
      drawPixel(graphOffsetX-4,y,1);
      drawPixel(graphOffsetX-5,y,1);
      if((y > lowerGraphLimit + 3) && (y < upperGraphLimit - 3)){
        TV.print(graphOffsetX - 9,y-3,i/4);
      }
    }
  }
}

void clearGraph(){
  TV.draw_rect(graphOffsetX - 1,graphOffsetY - graphHeight, graphWidth+1,graphHeight+1,1,0);
}

void drawData(int i, int val){
  // we use dispY[i] to store the displayed pixel. so we only need to
  // erase that pixel, and not the whole column.
  int y = val2y(val);
  int x = i + graphOffsetX;
  drawPixel(x,dispY[i],0);
  drawPixel(x,y,1);
  dispY[i] = y;
}

void drawData(int i, int v1, int v2){
  int u = val2y(v1);
  int v = val2y(v2);
  int x = i + graphOffsetX;
  TV.draw_column(x, graphOffsetY, graphOffsetY - graphHeight + 1, 0);
  u = min(max(u,lowerGraphLimit),upperGraphLimit);
  v = min(max(v,lowerGraphLimit),upperGraphLimit);
  TV.draw_column(x, u, v, 1);
}

void changeScaleFactor(){
  int i = 1;
  while(i < scaleFactor)
    i = i*2;
  scaleFactor = i / 2;
  if(scaleFactor == 0){
    scaleFactor = 1024/graphHeight+1;
  }
  offset = graphHeight/2 - avgValue/scaleFactor;
 
  // we need: 0/scaleFactor + offset >= 0 and 1024/scaleFactor + offset <= graphHeight
  offset = max(graphHeight - 1024/scaleFactor,offset);
  offset = min(0,offset);

  drawScale();
  clearGraph();
}

void changeSampleSize(){
  if(sampleSize<5)
    sampleSize = sampleSize + 1;
  else
    //sampleSize = sampleSize * 2;
    sampleSize = sampleSize * 8 / 5;
  if(sampleSize > 300){
    sampleSize = -4;
  }
  sampleTime = 0;
  clearGraph();
}

boolean scaleButtonPressed = false, sampleButtonPressed = false;
boolean checkButtons(){
  if(digitalRead(scalePin) == HIGH){
    scaleButtonPressed = true;
  }else{
    if(scaleButtonPressed){
      changeScaleFactor();
      scaleButtonPressed = false;
      return true;
    }
  }
  if(digitalRead(samplePin) == HIGH){
    sampleButtonPressed = true;
  }else{
    if(sampleButtonPressed){
      changeSampleSize();
      sampleButtonPressed = false;
      return true;
    }
  }
  return false;
}

float val2volts(int val){
  return val * 5 / 1024.0;
}

void printVolts(){
  TV.print(2,2,val2volts(avgValue),2);
  TV.print("V (");
  TV.print(val2volts(minValue),2);
  TV.print("V-");
  TV.print(val2volts(maxValue),2);
  TV.print("V)");
}

void printSampleRate(){
  long x = graphWidth;
  x = x*1000000/sampleTime;
  if(x > 9999){
    TV.print(85,2, x/1000);
    TV.print("kHz  ");
  }else{
    TV.print(85,2, x);
    TV.print("Hz ");
  }
  //TV.print(sampleSize);
  //TV.print("  ");
}

void loop() {
  checkButtons();
 
  waitFor(sampleSize,avgValue);

  minValue = 1024; maxValue = 0;
  long sum = 0;
  int i = 0; 
  startTime = micros();
  while(i < graphWidth){
    if(sampleSize <= 3){
      //for small sampleSize, sample first and then draw
      readFast(sampleSize);
      if (sampleTime > 0)
        sampleTime = (19 * sampleTime + micros() - startTime) / 20;
      else
        sampleTime = micros() - startTime;
      i=0;
      while(i < graphWidth){
        int val = data[i];
        minValue = min(minValue, val);
        maxValue = max(maxValue, val);
        if(sampleSize > 0)
          sum = sum + sampleSize*val;
        else
          sum = sum + val;
        drawData(i,val);
        i++;
      }
    }else{
      //for large samleSize, do sample and draw at the same time.
      int minV = 1024, maxV = 0;
      volatile int val = 0;

      initADC(1);
     
      ADCSRA |= (1<<ADSC); // start reading first value
      for(int j = 0; j< sampleSize; j++){

        while(!(ADCSRA & 0x10));
        val = ADCL;
        val += (ADCH << 8);
        ADCSRA |= (1<<ADSC); // already start reading next value for more speed

        minV = min(minV,val);
        maxV = max(maxV,val);
        sum = sum + val;
      }

      resetADC();

      drawData(i,minV,maxV);
      minValue = min(minValue,minV);
      maxValue = max(maxValue,maxV);
      i++;

      if(checkButtons()){
        //button has been pressed. reset values.
        i = 0;
        startTime  = micros();
        minValue = 1024; maxValue = 0;
        sum = 0;
      }
      if(i==graphWidth){
        if (sampleTime > 0)
          sampleTime = (9 * sampleTime + micros() - startTime) / 10;
        else
          sampleTime = micros() - startTime;
      }
    }
  }

  if(sampleSize > 0)
    avgValue =  sum / (graphWidth*sampleSize);
  else
    avgValue =  sum / graphWidth;
 
  printVolts();
  printSampleRate();
}

2
Salut amis Bidouilleurs,

Désolé pour la taille des images j'avais pas fait attention au pixel.... J'ai corrigé cela.
De l'ASM pour un Arduino bof bof je suis pas pro en ASM... Mais je sais qu'avec l'Arduino il est possible de contrôler directement les bit et réduire ainsi le code source au plus strict.
De plus il est possible de mettre une veille pendant une acquisition ce qui évite les bruits parasites et accélère l’acquisition sur le A0 car on peut directement mentionné le canal du MUX du convertisseur analogique.

J'ai un soucis de synchro d'affichage quand il échantillonne a quelques Hz au dessus des 300Hz sa passe bien... mais bon le moniteur est pas nouveau et toujours analogique lui aussi....
Enfin sa fait deux jour que je potasse le code source.... j'ai quelques éclaircies dans ma tête sur le code en même temps la page web que je cite dans la publication précédente apporte aussi un complément. et ajoute même une fonction HOLD à  la mesure... Mais bon le sujet n'est pas pour ici maintenant. dans l'organisation du code source du lien c'est a mon avis déjà  plus précis sur les temporisation etc.... mais bon je potasse..... J’espère sortir une bonne mouture de code source....

Edit 6/12/2020 10:05

une autre piste :
ceci pour controler plus en détail l'ADC de l’Arduino. Peut-être gagner en vitesse d’acquisition....
ADC tuto : http://www.robotplatform.com/knowledge/ADC/adc_tutorial_4.html
ou mieux encore : https://www.gammon.com.au/adc

3
Salut, Avec du vieux on fait du neuf, cela tombais a pic, j'avais un ancien moniteur de camera CRT...

Maintenant reste plus qu'a produire un code sources du code source optimisé....

Au passage j'ai trouvé ceci : http://radiopench.blog96.fc2.com/blog-entry-893.html avec un écran Oled. Une piste pour l'optimisation...

En attendant voila ma bidouille...
Un ancien écran CRT moniteur de camera de surveillance dont j'ai retiré le Switch de camera car a l’arrière on avait un connecteur pour brancher 4 cameras.
Donc il me restait un connecteur pour alimenter l’Arduino au travers d'un pont de diode filtrage et régulateur 5v. Ce moniteur possède donc un transformateur avec plusieurs enroulement.











Bonne bidouille...

4
Forum É-B: Règles de Conduite et Fonctionnement / Salut ! Présentation
« le: décembre 03, 2019, 04:58:06 pm »
Salut les bidouilleurs et bidouilleuses,

C'est Vincent, 40ans de Belgique province de liège (ON3VMC - JO20PN) La bidouille et la débrouille faire du neuf avec du vieux etc... c'est mon dada...
Déjà  quelques temps que je regarde les vidéos sur YouTube. Super travail.... La dernière EB333 (l'oscilloscope Arduino), M'a donné envie de mettre le pieds a l'étrier....

 

Pages: [1]