Spanningsbron met "Erg" hoge resolutie

All in One cursus : van idee naar uitvoering: mechanica,electronica,meettechniek,software,hardware, en nog veel meer vaardigheden.
Ik vind het super !

Moest ik effe kwijt.

De volgende stap is frutten met de ADC1115 converter

Daar heb ik wel een klein beetje ervaring mee.
IK gebruik niet de library van de ADC1115 en enkel wire commando's voor de I2c aansturing. JE moet dan enkel uit de datasheet alle instellingen even uitzoeken die je nodig hebt. Maar dat was verder vrij duidelijk voor mij.

blackdog

Golden Member

Hi benleentje,

Ik ben nu aan het worstelen met de ADS1115 en vooral met de verschillende library's.
Zelf helemaal de code uitzoeken vanuit de datasheet, is voor mij een drama...

Waar ik tegenaanloop is dit, als ik de proefcode draai, dan verspingt de code steeds van 19904 naar 19888 als ruwe bitwaarde als de maximale bitwaarde 32768 is.
Dat er eventueel wat ruis aanwezig is kan natuurlijk, maar niet steeds precies 16 LSB bits!
Dus er staat iets verkeerd of ik begrijp het niet goed, wat natuurlijk heel goed mogelijk is :-)

De proef code

c code:


#include <Wire.h>
#include <Adafruit_ADS1015.h>

Adafruit_ADS1115 ads(0x48);
float Voltage = 0.0;

void setup(void) 
{
  Serial.begin(9600);  
  ads.begin();
}

void loop(void) 
{
  int16_t adc0;  // we read from the ADC, we have a sixteen bit integer as a result

  adc0 = ads.readADC_SingleEnded(0);
  Voltage = (adc0 * 0.1875)/1000;
  
  Serial.print("AIN0: "); 
  Serial.print(adc0);
  Serial.print("\tVoltage: ");
  Serial.println(Voltage, 4);  
  Serial.println();
  
  delay(500);
}

Het lijkt er op dat de converter op 12 bit resolutie staat...
Even verder vroeten!

Groet,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"
blackdog

Golden Member

Hi,

Ik dacht dat ik gek was... vliegtuig, augurk, fietspompie < kijk dat komt er nu van :-)

Ik ruk een ander printje uit de voorraadbak ADC's en wat denken jullie TADA normale waarden, pffff.

Nu verder met andere dingen.

Groet,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"

Zelf helemaal de code uitzoeken vanuit de datasheet, is voor mij een drama...

Haha, dat heb ik nu met een datasheet van een opamp dat is voor mij nog steeds veel onbegrijpelijk.

Ik heb er zelf altijd een hekel aan als ik een chip aanstuur met een library en ik niet weet hoe nu precies werkt. HEt heeft ook even een tijdje geduurd voordat ik kon accepteren dat je niet perse in asm hoeft te programmeren omdat dat heerlijk dicht bij de cpu licht en ik dat vaak beter begrijp dat C code.
Maar met alle Arduino types en klonen is dat niet meer te doen.

blackdog

Golden Member

Hi benleentje :-)

We kunnen allemaal andere kunstjes...
Ben net gestopt omdat ik gaar was, maar wel na dat ik iemand had gevonden die de broodnodige aanpassingen had gedaan aan de ADAFRUIT ADS1115 Library.
Ongelovelijk hoe rommelig die is, belangrijke functies niet aan brengen zoals de sample rate.
Rommelige instellingen tussen de ADS1115 en de ADS1015, erg onduidelijk allemaal.
De aangepaste Library kan je wel de samplerate instellen, dus daar ben ik blij mee.

Nu nog afwegen of ik de samplerate hoog laat staan en dan zelf middel, of een lagere sampelrate gebruik van het IC.
Het heeft ook te maken met de invloed het sampelen van de ADC, op de looptijd.

Maar dat is voor morgen of een andere dag om uit te zoeken.
Wel nog testen gedaan in hoeverre er ruis staan op de ingangen, er is echt een lage impedantie nodig en/of stevig ontkoppelen met een condensator naar massa
om een zo stabiel mogelijke conversie te krijgen, zodat je niet te veel digids hoofd weg te gooien :-)

Groet,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"

Rommelige instellingen tussen de ADS1115 en de ADS1015, erg onduidelijk allemaal.

Daarom zei ik dat je hem niets moest gebruiken :). IK wist al dat het erg rommelig was maar had ook niet meer verder naar gekeken en wist daarom niet dat zelfs belangrijke dingen ontbraken.

Over het algemeen is I2C communicatie kort en krachtig en heb daarom maar zelf even die paar commando's die ik nodig had zelf samen gesteld.

Bij een LCD ligt het wel veel moeilijker omdat je dan ook zelf een buffer moet instellen om elke pixel op te slaan om het daarna in 1 keer naar het display te schrijven dus was erg blij dat ADAFruit wel goede library's maakt

[Bericht gewijzigd door benleentje op 16 december 2017 22:56:50 (22%)]

Gepost zaterdag 16 december 2017 21:00:15 |

Quoten

Hi benleentje,

Ik ben nu aan het worstelen met de ADS1115 en vooral met de verschillende library's.
Zelf helemaal de code uitzoeken vanuit de datasheet, is voor mij een drama...

Waar ik tegenaanloop is dit, als ik de proefcode draai, dan verspingt de code steeds van 19904 naar 19888 als ruwe bitwaarde als de maximale bitwaarde 32768 is.
Dat er eventueel wat ruis aanwezig is kan natuurlijk, maar niet steeds precies 16 LSB bits!
Dus er staat iets verkeerd of ik begrijp het niet goed, wat natuurlijk heel goed mogelijk is :-)

De proef code
c code:

#include <Wire.h>
#include <Adafruit_ADS1015.h>

Adafruit_ADS1115 ads(0x48);
float Voltage = 0.0;

void setup(void)
{
Serial.begin(9600);
ads.begin();
}

void loop(void)
{
int16_t adc0; // we read from the ADC, we have a sixteen bit integer as a result

adc0 = ads.readADC_SingleEnded(0);
Voltage = (adc0 * 0.1875)/1000;

Serial.print("AIN0: ");
Serial.print(adc0);
Serial.print("\tVoltage: ");
Serial.println(Voltage, 4);
Serial.println();

delay(500);
}

Het lijkt er op dat de converter op 12 bit resolutie staat...
Even verder vroeten!

Groet,
Bram

Hallo Blackdog,

Ik heb de Datasheet van de ADS115 niet heel aandachtig bestudeerd, maar ik zie al wat problemen met je code. De ADS1115 in single-ended mode meet relatief tot aan de GND van de ADS1115 tot aan zijn voedingspanning of +FS.
In de datasheet in hoofdstuk 10.1.2 staat dan het volgende:

The ADS111x offer a differential input voltage range of ±FSR. Single-ended configurations use only one-half of
the full-scale input voltage range
. Differential configurations maximize the dynamic range of the ADC, and
provide better common-mode noise rejection than single-ended configurations.

Dus je hebt al een bit minder aan resolutie in single-ended mode, omdat je de sign-bit mist.

Dus afhankelijk van je bereik instellingen meet je bijvoorbeeld in differentiaal mode ±0.256V en in single-ended van 0V tot +0.256V.
Let wel op dat de ADC geen negatieve signalen kan meten ten opzichte van de voedinsgspanning, ook bij differential-mode moeten de inputs binnen de voedingspanning blijven en de FSR instellingen.

Wat betreft de lage impedantie staat er het volgende in de data sheet in hoofdstuk 10.1.1:

The fully-differential voltage input of the ADS111x is ideal for connection to differential sources with moderately
low source impedance, such as thermocouples and thermistors. Although the ADS111x can read bipolar
differential signals, these devices cannot accept negative voltages on either input.

Voor hogere impedanties moet je gewoon een buffer toevoegen net als alle andere ADCs die geen interene buffer opamp hebben.

Wat betreft je code, ben je wat wazig met je ADC meet resultaten en de spanningswaardes die uit je berekening komen. Als je ADC waarde 32768 is dit hexadecimaal 0x8000. Een unsigned int is 16 bits groot en de laatste bit (nummer 15) is een sign-bit! Een unsigned int heeft een maximale bereik van +32767 tot -32768. Je gaat dus met een ADC waarde van 32768 buiten de unsigned int's zijn bereik en het getal wordt dan negatief omdat de sign bit 1 is.

Daarnaast nog wat problemen in je berekening, waar je verschillende type getallen gebruikt:

c code:

int16_t adc0;  // we read from the ADC, we have a sixteen bit integer as a result
adc0 = ads.readADC_SingleEnded(0);
Voltage = (adc0 * 0.1875)/1000;

Je ADC resultaat is een unsigned int die je vermenigvuldigd met een float en vervolgens deel je door een (un)signed getal 1000 (je vergeet de .0 voor een float getal). Nu weet ik niet wat de compiler hier van maakt met al die verschillende variabele types, maar als die zich houdt aan de limitaties van alle verschillende getallen, kan je resultaat afwijken, aangezien de deling door 1000 als een (un)signed getal wordt uitgevoerd en het resultaat dus geen getallen achter de komma heeft bijvoorbeeld.

Als je al je variabelen bij je berekening een float maakt heb je geen last meer van de limitaties van je verschillende variabelen. Dus:

c code:

int16_t adc0;  
adc0 = ads.readADC_SingleEnded(0);
Voltage = ((((float))adc0) * 0.1875)/1000.0; // Cast the unsigned int to a float before multiplication

Ik vindt ook de Arduino omgeving erg onhandig aangezien je niet kan debuggen en je alles serieel moet printen om er achter te komen wat er fout gaat. Helaas zijn de grote aantallen libraries wel erg handig om even snel wat voor elkaar te krijgen met de ebay chips en displays. Ik gebruik zelf als ik iets moet doen met een Arduino platform gewoon Atmel Studio met de vMicro plug-in (gratis versie) die het dan de Arduino IDE functies zoals uploaden en de seriele terminal toevoegd aan Atmel Studio. Niet dat dit de heilige graal is qua ontwikkelen aangezien je nog steeds niet kan debuggen, maar dan het je tenmiste een iets betere tekst verwerker dan de Arduino IDE.

blackdog

Golden Member

Ha die Radiohead :-)

Ik ben op de hoogte van hoe er gewerkt moet worden met de ADS1115.
Dat je maar 15 bit hebt voor unipolair gebruik was mij ook al lang duidelijk. (heb dat zeker een jaar geleden al uitgezocht)

Of ik een buffer ga gebruiken, dat hangt af hoe ik allerlij andere problemen ga oplossen, die met ranging te maken heeft.
Als ik wat verder ben met hoe ik de ingang schakeling samen met het samplen en de gain setting in de ADS1115 ga oplossen,
zal ik dat hier laten zien met mijn afwegingen overhet hoe en waarom.

Mijn opmerking over lage impedantie had betrekking op de ruis aan de ingang, dat is dus met filtering op te lossen. (condensator van de ingang naar massa)
Als dit tenminste niet de responstijd te veel aantast, dat is dus één van mijn onderzoek punten.

Wat betreft de code die ik liet, dat is een stukje uit de proefcode uit de library, goed genoeg voor een eerst beeld.
Met deze proefstukjes code (heb er meerdere gebruikt, kwam ik er dus achter met zo'n stukje proefcode, dat een van mijn ADS1115 printjes rot was :-)
Ik zal je opmerking over de "Floats" even opslaan :-)
Ik maak gebruik van de Arduino IDE versie 1.8.4

Atmel Studio heb ik begin dit jaar ge-installeerd gehad, daar wert ik gillend gek van...
Laten we het er op houden, dat dit programma bij mij geen enkel liefde opwekt. *grin*

Bij het meeste wat ik wil doen, kan met de Arduino IDE, ik zal echter nooit een Prof. coder worden,
maar kan nu al aardig wat schakel logica maken voor mijn ontworpen meetinstrumentjes.

Dank voor je input.

Groet,
Blackdog

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"
blackdog

Golden Member

Hi,

Net al de vorige keren loop ik vast met de weergave van de uitkomsten.
Ik denk dat het te maken heeft met wat Radiohead al aan gaf betreffende floats en dat ik niet weet hoe ik goed moet rekenen met de Arduino.

Of misschien iets anders wat ik nog niet weet of weer vergeten ben :-)

Waar heb ik het over, zie de code hieronder waarmee ik aan het testen ben.
Waar ik ondertussn uit ben, is dat ik in de software niet de ADC output ga middelen.
Ik heb testen gedaan met een 10 slagen potmeter aan een 9V batterij en dat geeft een heel vervelend effect bij het instellen van een bepaalde uitgangsspanning.
Het werkt veel prettiger door de ADC op 8 samples/sec te zetten, hebben we dat hoofdstuk ook afgesloten.

Nu ben ik aan het uitzoeken en testen hoe ik de drie bereiken ga meten aan de uitgang van de spanningsbron.
Het 2V bereik is simpel, daarvoor kan ik de "ads.setGain(GAIN_TWO)" setting gebruiken wat iets meer dan 2V volle schaal geeft via ingang-1
Het 20V bereik kan ik dan met een spanningsdeler doen van 1:10, deze kan dan aan zeg ingang-0 hangen.
En als laatste het 20mV bereik hiervoor stel ik dan de gain in de ADS in op "ads.setGain(GAIN_SIXTEEN)"
Dit is eigenlijk niet voldoende, en voor optimaal dynamisch bereik zou hier een 10x verster nodig zijn zodat de resolutie iets minder word dan 1uV per bit.

Mooi, dan weten jullie nu waar ik mee bezich ben uit te zoeken.
Eerst de code dan de uiteindelijke vraag.

c code:


#include <Wire.h>
#include <Adafruit_ADS1015.h>

Adafruit_ADS1115 ads;     // Use this for the 16-bit version 

float Voltage = 0;


void setup(void) {

  Serial.begin(115200);

  //   ads.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3mV      0.1875mV (default)
  // ads.setGain(GAIN_ONE);        // 1x gain   +/- 4.096V  1 bit = 2mV      0.125mV
  // ads.setGain(GAIN_TWO);        // 2x gain   +/- 2.048V  1 bit = 1mV      0.0625mV
  // ads.setGain(GAIN_FOUR);       // 4x gain   +/- 1.024V  1 bit = 0.5mV    0.03125mV
  // ads.setGain(GAIN_EIGHT);      // 8x gain   +/- 0.512V  1 bit = 0.25mV   0.015625mV
   ads.setGain(GAIN_SIXTEEN);    // 16x gain  +/- 0.256V  1 bit = 0.125mV  0.0078125mV

   ads.begin();
  
   ads.setSPS(ADS1115_DR_8SPS);                      // for ADS1115 fastest samples per second is 860 (default is 128)
}


void loop(void) {

unsigned long start = millis();  

Serial.println(1000.0F*ads.readADC_SingleEnded_V(0));

unsigned long end = millis();
unsigned long delta = end - start;
Serial.println(delta);

}

Het stukje code is zeer simpel, als extra meet ik de tijd dat het kost om de ADC uit te lezen, komt overheen met de 8 samples per seconde, rond de 125 tot 130mSec.
De waarde zit dicht genoeg bij de datasheet waarde, dus het is niet nodig zeg 100 metingen te doen hiervoor.

Mooi daar komt hij dan, ik bied 37,164532mV aan en in de Serial monitor zie ik 32.16 al mV staan.
Ik mis dus heel veel digits achter de komma, dat ze er wel zijn heb ik getest door de uitgang van de ADC eerst met 1000 te vermedigvuldigen.

Dus welke truc moet ik uithalen om alle digids weer tegeven?

Dank en groet,
Blackdog

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"
Hewlett

Honourable Member

Je moet bij je Serial.println aanroep een tweede parameter opgeven waarbij je voor floating point types (in de println aanroep vindt een floating point promotie plaats omdat je daar met een float rekent) het aantal posities achter de komma opgeeft. Default is dat 2, vandaar de 32.16 wanneer de ADC 37,164532mV leest.

Zoiets dus:

c code:


Serial.println(1000.0F*ads.readADC_SingleEnded_V(0), 6);
HamRadio PA2HK // Keep Calm and Carry On.
blackdog

Golden Member

Werkt! :-)

Natuurlijk had ik al in die richting gezocht, maar vergeet dan weer de comma :-(

Dank Hessel!

Groet,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"

<Edit 29/12/2017>

Even met de ADS1115 aan het spelen geweest, hieronder geteste code:

c code:

#include <Wire.h> // specify use of Wire.h library
#define ASD1115 0x48 // ADR connected to GND

unsigned int val = 0;
byte conf[2];
byte buffer[2];

const float VPS = 4.096 / 32768.0; // volts per step

void setup()   {

  Serial.begin(9600); 
  Wire.begin(); // begin I2C

  // ASD1115
  // set config register and start conversion
  // ANC1 and GND, 4.096v, 128s/s
  
  conf[0] = 0b11010010; // 0xD2 single shot off
                            // bit 15 flag bit for single shot
                            // Bits 14-12 input selection:
                              // 100 ANC0; 101 ANC1; 110 ANC2; 111 ANC3
                            // Bits 11-9 Amp gain. Default to 010 here
                            // Bit 8 Operational mode of the ADS1115.
                              // 0 : Continuous conversion mode
                              // 1 : Power-down single-shot mode (default)

  conf[1] = 0b10000101; // bits 7-0  0x85
                            // Bits 7-5 data rate default to 100 for 128SPS
                            // Bits 4-0  comparator functions see spec sheet.

  // setup ADS1115
  Wire.beginTransmission(ASD1115); 
  Wire.write(1);            // Select config register
  Wire.write(conf[0]);
  Wire.write(conf[1]);  
  Wire.endTransmission();  

  delay(500);

}  // end setup

void loop() {

  Wire.beginTransmission(ASD1115);
  Wire.write(0);            // Select result register
  Wire.endTransmission();

  Wire.requestFrom(ASD1115, 2);
  buffer[0] = Wire.read();  // 
  buffer[1] = Wire.read();  // 
  Wire.endTransmission();  

  // convert display results
  val = buffer[0] << 8 | buffer[1]; 

  if (val > 32768) val = 0;

  Serial.println(val * VPS);
  Serial.println(val);
  
  delay(1000);

} // end loop

[Bericht gewijzigd door Roland van Leusden op 29 december 2017 00:09:06 (76%)]

It's the rule that you live by and die for It's the one thing you can't deny Even though you don't know what the price is. It is justified.
blackdog

Golden Member

Hi,

Er was weer wat tijd beschikbaar om te sleutelen aan de Arduino code en de aandacht ging deze keer uit naar een ander display.
De rede was, dat ik met het Nokia display moeite had de gemeten spanning duidelijk genoeg op het display te krijgen
door het te kort aan goede font's in de library die ik gebruikte.

Ik heb vier verschillende TFT displays getest en wat een horror...
Getergt door de Chinese idioten die verschillende display op de zelfde driver monteren of vise versa.
Een driver voor voor 128x160 en daar dan een 128x128 display op monteren enz, enz, leve de "mini breinen!".
En dan het ik het nog niet gehad over hoe de aansluitpinnen iedere keer verschillend genoemd worden.
Ondertussen ben ik er wel achter, dat je gewoon pin-11 en pin-13 moet gaan gebruiken voor hardware SPI, die liggen in ieder geval vast.
software SPI kan natuurlijk ook, maar dan ben je snel aan de Goden over geleverd, en daar heb je weinig aan als je van Nietzsche houd *grin*

Verder ook een positief geluid, en dat is de driver bouwer: olikraus
Geweldig zoals de ucglib library is gedocumenteerd, er zijn drie uitgebreide PDF bestanden aanwezig met uitleg.
Ook veel font met plaatjes hoe ze er uit zien, hulde!

Ik moet nog een testje doen met pin-12, kijken of deze werkt als digitale uitgang voor het lampje in de Output Enable schakelaar.
Werkt dat niet, dan moet de ruimte die ik op het display heb gereserveerd, maar voldoende zijn.

Het linker display kreeg ik op geen enkele manier goed werkend veel alias effecten, geen idee hoe dit mogelijk is.
Misschien toch weer een driver probleem, waar ik er toch een paar van geprobeerd heb.
Rechts met het rode printje is het soort waar ik hieronder een plaatje van laat zien met text er op, alleen zijn er drie of vier versies van met verschillende chips!!!
Dan het ik het nog niet gehad over de 3,3 en 5V problemen, ja ja, erg comfortabel allemaal.
http://www.bramcam.nl/NA/LowCostCal/LowCostCal-76.png

En dan de font opset van het display, de text in het midden geeft de waarde van de ADC aan, wat op dit plaatje gewoon text is die in de code staat.
Ik heb geprobeerd de text zo groot en duidelijk mogelijk weer te geven, dit samen met de mogelijkheid met V of mV achterde waarde te plaatsen.
Het gele kader om de centrale waarde heb ik met opset wat dikker gemaakt zodat je ogen bij de eerste blik zo snel mogelijk naar de ADC waarde gaan.
De text in groen "Output On!" veranderd in de kleur rood als de "Output Off!" is.
http://www.bramcam.nl/NA/LowCostCal/LowCostCal-75.png

Temperatuur meting
Ook staat nu bovenin ook een temperatuur weergegeven, dat wordt de temperatuur van het "boxje" waar de potmeters en het analoge printje in komt.
Dit "boxje" soldeer ik van printmateriaal in elkaar en krijgt een laagje piepschuim er omheen.
Dit om de temperatuur zo stabiel mogelijk te houden (langzame drift die er altijd is minder te maken).
De potmeters worden vrijwel zeker niet aan het front vast gezet en uitgrust met een plastick knop.
Dit om de warmte overdracht van het frontje niet naar de potmeters over te brengen.
Ik had al aangegeven, dat de potmeters de grootste drifters zijn in mijn precisie versie.
Door wat extra aandacht hieraan te besteden kan ik de drift van de potmeters enigzins beheersen.
Het geheel in een oventje zetten gaat me te ver, want het is geen kalibrator! :-)

De testcode voor het display om te zien hoe de text er uitziet op dit display.

c code:


#include <SPI.h>
#include "Ucglib.h"
    
Ucglib_ST7735_18x128x160_HWSPI ucg(/*cd=*/ 9, /*cs=*/ 10, /*reset=*/ 8);

void setup(void)
{
  delay(10);
  ucg.begin(UCG_FONT_MODE_TRANSPARENT);
  ucg.clearScreen();
}

void loop(void)
{
  ucg.setRotate90();

  ucg.setColor(255, 255, 255);
  ucg.drawFrame(0, 0, 128, 128);
  ucg.drawLine(0, 23, 128, 23);
  ucg.setColor(0, 255, 255);
  ucg.drawLine(0, 44, 0, 76);
  ucg.drawLine(1, 44, 1, 76);
  ucg.drawLine(126, 44, 126, 76);
  ucg.drawLine(127, 44, 127, 76);  
  ucg.drawLine(0, 44, 128, 44);
  ucg.drawLine(0, 45, 128, 45);
  ucg.drawLine(0, 46, 128, 46);  
  ucg.drawLine(0, 76, 128, 76); 
  ucg.drawLine(0, 77, 128, 77);
  ucg.drawLine(0, 78, 128, 78);
  ucg.setColor(255, 255, 255);
  ucg.drawLine(0, 102, 128, 102);

  ucg.setPrintPos(21,122);                   // Product name
  ucg.setColor(0, 255, 255, 0);
  ucg.print("NoiseAmp");

  ucg.setFont(ucg_font_courB10_tr);         //  Reference section temperature
  ucg.setColor(0, 255, 255, 255);
  ucg.setPrintPos(6,16);
  ucg.print("RefTemp 24.5C");

  ucg.setFont(ucg_font_courB14_tf);         //  Output Enable
  ucg.setColor(0, 0, 255, 0);
  ucg.setPrintPos(12,96);
  ucg.print("Output ON!");
  
  ucg.setFont(ucg_font_courB10_tf);         // Rage text for display
  ucg.setColor(0, 0, 255, 0);
  ucg.setPrintPos(10,38);
  ucg.print("RANGE:  20mV");
    
  ucg.setFont(ucg_font_logisoso20_tn);      // Measured output voltage
  ucg.setColor(0, 0, 255, 255);
  ucg.setPrintPos(1,72);
  ucg.print("19,2748");

  ucg.setFont(ucg_font_logisoso16_hf);       // V, mV anouncer
  ucg.setColor(255, 255, 255);
  ucg.setPrintPos(98,72);
  ucg.print("mV");

  delay(50);  
}

Genoeg voor nu, shoot @ it!

Groet,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"
blackdog

Golden Member

Hi!

HELP!

*grin*

Bijna alle code heb ik nu bij elkaar, de text staat netjes op het display, de buttons werken zoals het moet en de text op het display loopt mooi mee met de functie toetsen.
Ook de 1x in de 5 a 10 Seconde de temperatuur op het beeld zetten gaat goed.

Dat was toch wel even worstelen toen de ADS1115 er bij kwam, om de uitgangsspanning uit op het scherm te krijgen, de SE95 en de ADS1115 zaten elkaar lekker in de weg.
Dit samen met dat de SE95 toch iets anders is dan de LM75 waar de library voor bedoeld is die ik gebruikt.
Maar door het adres van de SE95 en de ADS1115 hard in de library zetten ging het gezamelijk werken, moet ik het alleen niet vergeten te noteren :-)

Maar nu het probleem, ondanks dat dit display "snel" wordt genoemd, is de ververs snelheid bagger!
Voor het aansturen gebruik is hardware SPI, maar dan nog is het één en al flikker wat de klok slaat.

Voor de gene die nu weer gaan zeggen, programeer het dan maar in b.v. "C", doe dat maar niet, dit gaat niet gebeuren :-)

Ik zal even laten weten waar ik mee bezig ben, je kan de tekst of nummerieke waarde niet gewoon updaten, ik bedoel dan dat de waarde ververst wordt zoals je dit verwacht.
Er blijft dan residu achter van de vorige waarde, dit los ik de ene keer op met het plaatsen van zeg een zwart of gekleurt vakje over de oude tekst,
dan schrijf ik daar dan weer de nieuwe tekst overheen.
Dit kunen jullie zien bij de blauwe achtergrondjes voor de "Range" waarde en de weergave of de "Output"ON! of OFF! is.

Bij de temperatuur heb ik voor een andere manier gekozen, ik lees de SE95 sensor uit en plaats de waarde in een variabele.
En een tweede variabel die update ik aan het einde van de meting, dat gaat op deze manier => oldTemp = celsius;
Dit stukje staat helemaal aan het begin van de: void loop() {
Ik overschrijf dan de oude waarde met een zwarte textkleur en plaats daarna de nieuwe text hier weer overheen.
Dit gaat vrij goed, maar kan nog beter door een vergelijking te gaan doen of de waarde wel veranderd is,
is de waarde uit de sensor nog gelijk, dan kan de loop gewoon weer verder gaan met ander werk.

Dit stukje code wordt denk ik nog op een andere plek geplaatst, waarschijnlijk samen met de code van de ADC, dit leg ik later uit.
Dat de temperatuur waarde nu 1x per 5 of 10 seconde even heel kort knippert is eigenlijk in het geheel niet van belang,
maar met een mix van wat andere code in de loop, zorgt er voor dit ik dit beter moet gaan timen. (slechter reageren van de buttons)
Zoals alleen een temperatuur meting doen als de ADC in rust is.
Misschien ook voor alleen de Output Enable schakelaar een interrupt ingang gebruiken, daar ik deze altijd snel reagerend wil hebben.

Nu eerst even de code die ik tot nu toe heb geschreven, er staat zeer veel uitleg bij maar is ook nu weer niet helemaal af.

c code:


// NoiseAmp Amsterdam
// High Resolution voltage source
// Thanks to: Olikraus, Arduino, Michael Adams (Buttons), Simon Monk (Timer.h)
// This software controls Bi-Polaire Relay's, Read Buttons and display information on a 128*128 LCD Display
// 
// The LM75 library is used toe readout a SE95 NXP temperature sensor.
// This sensor wil give a impression of the temperature of the potmeters and reference section who are in a appart shielded box
//
//
//
// The part of the software i wrote, is free for personal use :-)


#include <TimeLib.h>
#include <Wire.h>
#include <Button.h>
#include "Timer.h"
#include "Ucglib.h"
#include <LM75.h>
#include <Adafruit_ADS1015.h>

Adafruit_ADS1115 ads;     // Use this for the 16-bit version 
float Voltage = 0;

// initialize an LM75 object
LM75 sensor;

// initialize Display driver object
Ucglib_ST7735_18x128x160_HWSPI ucg(/*cd=*/ 9, /*cs=*/ 10, /*reset=*/ 8);

// Setup variable for temperature measurement
float  celsius = 0;
float  oldTemp = 0;
unsigned long currentTime;
unsigned long loopTime;

// Setup Range RangeState used for the Display
byte rangeState = 1;                                // RangeState 1 = 20mV Range, 2 = 2V Range, 3 = 20V Range, used for error detection and Display, Power On Preset = 1 (20mV range)

// Setup variable for timing relais driver puls
byte resetPuls = 5;                                 // Time in mSec for Reset Puls
byte wait_2 = 2;                                    // Get Stable, Delay
byte on_Puls_5 = 5;                                 // Relais timing 5mSec ("On" time for "Set" coil of the relais )

// Setup variable for toggle Relaiy Setup (Output On/Off)
byte enable = 0;                                    // 0 = Output Off, 1 = Output On, Power On Preset = 0
byte Enable_In = A0;                                // Toggle Button Pin Setup
byte Enable_Out = 12;                               // Relais driver output setup, used for indicator light
byte ToggleState = HIGH;                             // Preset Enable Output Set To "Off"
byte reading;                                       // The current reading from the input pin
int previous = LOW;                                 // The previous reading from the input pin
long time = 0;                                      // The last time the output pin was toggled
long debounce = 200;                                // The debounce time, increase if the output flickers

// initialize timer library
Timer t;

// Define Range Buttons connected tot a Arduino Nano
Button button2(A1);                                 // 20mV range
Button button3(A2);                                 // 2V range
Button button4(A3);                                 // 20V range



void setup() {

  Wire.begin();

//Setup Arduino relais outputs
  pinMode(2, OUTPUT);                                // ResetPuls Relay Driver
  pinMode(3, OUTPUT);                                // RE-2 Driver (20/2V)
  pinMode(4, OUTPUT);                                // RE-3 Driver
  pinMode(5, OUTPUT);                                // RE-4 Driver
  pinMode(6, OUTPUT);                                // RE-1 Set driver
  pinMode(7, OUTPUT);                                // RE-1 Reset driver
  pinMode(12, OUTPUT);                               // Output Driver for LED Enable Button )

// Output Enable function setup
  pinMode(A0, INPUT);                                // Set pin-A0 as a input for the enable button

//Setup Arduino range button inputs
  button2.begin();                                   // 20V Range
  button3.begin();                                   // 2V Range
  button4.begin();                                   // 20mV Range


// Timing setup for Temperature measurement samples
  currentTime = millis();
  loopTime = currentTime;

// Setup Display
  ucg.begin(UCG_FONT_MODE_TRANSPARENT);
  ucg.clearScreen();

// Set static Lines on Display
  ucg.setRotate90(); 
  ucg.setColor(255, 255, 255);
  ucg.drawFrame(0, 0, 128, 128);
  ucg.drawLine(0, 23, 128, 23);
  ucg.setColor(0, 255, 255);
  ucg.drawLine(0, 44, 0, 76);
  ucg.drawLine(1, 44, 1, 76);
  ucg.drawLine(126, 44, 126, 76);
  ucg.drawLine(127, 44, 127, 76);  
  ucg.drawLine(0, 44, 128, 44);
  ucg.drawLine(0, 45, 128, 45);
  ucg.drawLine(0, 46, 128, 46);  
  ucg.drawLine(0, 76, 128, 76); 
  ucg.drawLine(0, 77, 128, 77);
  ucg.drawLine(0, 78, 128, 78);
  ucg.setColor(255, 255, 255);
  ucg.drawLine(0, 102, 128, 102);


// Set static text on display Produc Name
  ucg.setFont(ucg_font_courB12_tr);                 // Set font type
  ucg.setColor(0, 255, 255, 0);                     // Switch color to blue
  ucg.setPrintPos(21,122);                          // Set position for "NoiseAmp" text
  ucg.print("NoiseAmp");                            // Place "NoiseAmp" on display

// Set static text on display for te output status
  ucg.setFont(ucg_font_courB12_tr);                 // Set font type
  ucg.setColor(0, 255, 255, 255);                   // Switch color to green
  ucg.setPrintPos(4,95);                            // Set position for "Output:" text
  ucg.print("Output:");                             // Place "Output:" on display

// Set static text on display for temperature
  ucg.setFont(ucg_font_courB12_tr);                 // Set font type 
  ucg.setColor(0, 255, 255, 255);                   // Switch color to green
  ucg.setPrintPos(4,17);                            // Set position for "Output:" text
  ucg.print("Temp:      C");                        // Place "Temp:      C" on display

// Set static text on display for te range
  ucg.setFont(ucg_font_courB12_tr);                 // Range text for display
  ucg.setColor(0, 255, 255, 255);                   // Switch color to green
  ucg.setPrintPos(4,38);                            // Set position for "Range:" text
  ucg.print("Range:");                              // Place "Range:" on display


// Power On Preset
  digitalWrite(5, HIGH);                            // Start reset puls
  delay(resetPuls);                                 // "resetPulse" defines the time how long the relay "reset coil" gets drive current (here 5 mSec)
  digitalWrite(5, LOW);                             // Stop reset puls  

  // Place default range on screen
  ucg.setColor(0, 255, 0, 0);                        // Change color to blue
  ucg.setPrintPos(50,17);                            // Position for drawing black box to erase last value
  ucg.drawRBox(78, 26, 46, 16, 4);                   // Draw blue box
  ucg.setFont(ucg_font_courB12_tr);                  // Font type
  ucg.setColor(255, 255, 255);                       // Font color
  ucg.setPrintPos(81,40);                            // Font position
  ucg.print("20mV");                                  // V announcer

  // Place mV announcer voor ADC value on screen afther boot
  ucg.setColor(255, 255, 255);                       // Set color to white
  ucg.setFont(ucg_font_logisoso16_hf);               // Font type
  ucg.setPrintPos(99,70);                            // Font position
  ucg.print("mV");                                   // mV announcer


// Setup ADC
  ads.setGain(GAIN_TWO);                             // 2x gain   +/- 2.048V  1 bit = 1mV      0.0625mV
  ads.begin();
  ads.setSPS(ADS1115_DR_8SPS);                       // for ADS1115 fastest samples per second is 860 (default is 128)
}


void loop() {

// Start to measure temperature
  currentTime = millis();
  if(currentTime >= (loopTime + 5000)){              // Every 5 second sample temperature
  ucg.setFont(ucg_font_courB12_tr);                  // Set font type
  ucg.setColor(0, 0, 0, 0);                          // Switch color to black
  ucg.setPrintPos(58,17);                            // Set position "wipe out" text
  ucg.print(oldTemp);                                // Overwrite old temperature value with black fonts
  ucg.setColor(0, 255, 255, 255);                    // Switch color to white  
  sensor.shutdown(false);                            // Switch on SE95 temp sensor
  celsius = (sensor.temp());                         // Put temperature in celsius variable
  ucg.setPrintPos(58,17);                            // Set position for writing new temperature value
  ucg.print(celsius);                                // Place measured temperature on the screen
  sensor.shutdown(true);                             // Switch off SE95 sensor
  oldTemp = celsius;                                 // Updates oldTemp 
  loopTime = currentTime;                            // Update loopTime
  }
  else
// End measure temperature


// Start reading toggle Enable/Disable button code 
    reading = digitalRead(A0);                       // Read if button is pushed
    if (reading == HIGH && previous == LOW && millis() - time > debounce) {
    if (ToggleState == HIGH)
    ToggleState = LOW;
    else
    ToggleState = HIGH;
    time = millis();    

    // Toggle RE-1 comparator start
    if(ToggleState==1) {
    digitalWrite(6, HIGH);                           // Makes output-6 High
    delay(on_Puls_5);                                // Time for "On" puls (5 mSec)
    digitalWrite(6, LOW);                            // Makes output-6 low

  // Update display with "ON!" text
  ucg.setColor(0, 255, 0, 0);                        // Change color to blue
  ucg.drawRBox(78, 82, 46, 16, 4);                   // Draw blue box
  ucg.setFont(ucg_font_courB12_tr);                  // Font type
  ucg.setColor(255, 255, 255);                       // Font color
  ucg.setPrintPos(89,96);                            // Font position
  ucg.print("ON!");                                  // V announcer


  } else if(ToggleState==0) {
  digitalWrite(12, HIGH);                            // Makes output 12 High
  delay(on_Puls_5);                                  // Time for "On" puls (5 mSec)
  digitalWrite(12, LOW);                             // Makes output 12 low

  // Update display with "ON!" text
  ucg.setColor(0, 0, 0, 255);                        // Change color to blue
  ucg.drawRBox(78, 82, 46, 16, 4);                   // Draw blue box
  ucg.setFont(ucg_font_courB12_tr);                  // Font type
  ucg.setColor(255, 255, 255);                       // Font color
  ucg.setPrintPos(83,95);                            // Font position
  ucg.print("OFF!");                                  // V announcer
  } 
  }
  digitalWrite(12, ToggleState);
  previous = reading;
// End toggle Enable/Disable button code



// Start reading 20V range button code
  if (button4.pressed()) {

  // wipe old value and set announcer to V 
  ucg.setColor(0, 0, 0, 0);                          // Change color to black
  ucg.setPrintPos(50,17);                            // Position for drawing black box to erase last value
  ucg.drawBox(99, 52, 26, 19);                       // Draw black box
  ucg.setFont(ucg_font_logisoso16_hf);               // Font type
  ucg.setColor(255, 255, 255);                       // Font color
  ucg.setPrintPos(115,70);                           // Font position
  ucg.print("V");                                    // V announcer

  ucg.setColor(0, 255, 0, 0);                        // Change color to blue
  ucg.setPrintPos(50,17);                            // Position for drawing black box to erase last value
  ucg.drawRBox(78, 26, 46, 16, 4);                   // Draw blue box
  ucg.setFont(ucg_font_courB12_tr);                  // Font type
  ucg.setColor(255, 255, 255);                       // Font color
  ucg.setPrintPos(86,40);                            // Font position
  ucg.print("20V");                                  // V announcer
 
  // Reset Relais-2, Relais-3, Relais-4
  digitalWrite(5, HIGH);                             // Start reset puls
  delay(resetPuls);                                  // reset Pulse defines the time how long the relay "reset coil" gets current
  digitalWrite(5, LOW);                              // Start reset puls
  delay(wait_2);                                     // Wait a short wile

  // Start On puls Relais-2, 3, 4
  digitalWrite(2, HIGH);                             // Start setpuls 
  digitalWrite(3, HIGH);                             // Start setpuls
  digitalWrite(4, HIGH);                             // Start setpuls
  delay(on_Puls_5);                                  // 5mSec Setpuls Relais-2, 3, 4
  
  // Stop On Puls Relais-2, 3, 4
  digitalWrite(2, LOW);                              // End set puls
  digitalWrite(3, LOW);                              // End set puls
  digitalWrite(4, LOW);                              // End set puls
  rangeState = 3;                                    // Set range state for Display
  }
// End reading 20V range button code


// Start reading 2V range button code
  if (button3.pressed()) {
  
  // wipe old value and set announcer to mV 
  ucg.setColor(0, 0, 0, 0);                          // Change color to black
  ucg.setPrintPos(50,17);                            // Position for drawing black box to erase last value
  ucg.drawBox(99, 52, 26, 19);                       // Draw black box
  ucg.setFont(ucg_font_logisoso16_hf);               // Font type
  ucg.setColor(255, 255, 255);                       // Font color
  ucg.setPrintPos(115,70);                           // Font position
  ucg.print("V");                                    // V announcer

  ucg.setColor(0, 255, 0, 0);                        // Change color to blue
  ucg.setPrintPos(50,17);                            // Position for drawing black box to erase last value
  ucg.drawRBox(78, 26, 46, 16, 4);                   // Draw blue box
  ucg.setFont(ucg_font_courB12_tr);                  // Font type
  ucg.setColor(255, 255, 255);                       // Font color
  ucg.setPrintPos(92,40);                            // Font position
  ucg.print("2V");                                   // V announcer
 
  // Reset Puls Relais-2, Relais-3, Relais-4
  digitalWrite(5, HIGH);                             // Start reset puls
  delay(resetPuls);                                  // reset Pulse defines the time how long the relay "reset coil" gets current
  digitalWrite(5, LOW);                              // End reset puls
  delay(wait_2);                                     // Wait a short wile
  // Set Puls Relais-3, Relais-4
  digitalWrite(3, HIGH);                             // Start set puls
  digitalWrite(4, HIGH);                             // Start set puls
  delay(on_Puls_5);                                  // 5mSec timing for Setpuls Relais-3, Relais-4
  digitalWrite(3, LOW);                              // End set puls  
  digitalWrite(4, LOW);                              // End set puls
  rangeState = 2;                                    // Set range state for Display
  }
// End reading 2V range button code


// Start reading 20mV range button code
  if (button2.pressed()) {
  
  // wipe old value and set announcer to mV 
  ucg.setColor(0, 0, 0, 0);                          // Change color to black
  ucg.setPrintPos(50,17);                            // Position for drawing black box to erase last value
  ucg.drawBox(99, 52, 26, 19);                       // Draw black box
  ucg.setColor(255, 255, 255);                       // Set color to white
  ucg.setFont(ucg_font_logisoso16_hf);               // Font type
  ucg.setPrintPos(99,70);                            // Font position
  ucg.print("mV");                                   // mV announcer

  ucg.setColor(0, 255, 0, 0);                        // Change color to blue
  ucg.setPrintPos(50,17);                            // Position for drawing black box to erase last value
  ucg.drawRBox(78, 26, 46, 16, 4);                   // Draw blue box
  ucg.setFont(ucg_font_courB12_tr);                  // Font type
  ucg.setColor(255, 255, 255);                       // Font color
  ucg.setPrintPos(81,40);                            // Font position
  ucg.print("20mV");                                  // V announcer
  
  // Reset Puls Relais-2, Relais-3, Relais-4
  digitalWrite(5, HIGH);                             // Start reset puls
  delay(resetPuls);                                  // reset Pulse defines the time how long the relay "reset coil" gets current
  digitalWrite(5, LOW);                              // End set puls 
  rangeState = 1;                                    // Set range state for Display 
 }
// End reading 20mV range button code


// ADC measure input and place value on displag
  ucg.setColor(0, 0, 0, 0);                          // Change color to black
  ucg.setPrintPos(1,17);                             // Position for drawing black box to erase last value
  ucg.drawBox(1, 52, 88, 19);                        // Draw black box
  ucg.setFont(ucg_font_logisoso16_hf);               // Font type
  ucg.setColor(0, 255, 0);                           // Font color
  ucg.setPrintPos(8,70);                             // Font position
  ucg.print(1000.0F*ads.readADC_SingleEnded_V(0), 2); 


 }

Het onderste stukje is dus de code die de ADS1115 uitleest en op het scherm plaatst.
De ADS1115 staat ingesteld op 8 samples per seconde voor de meest stabiele resultaat.
Open op het breadboard blijft b.v. 1000,8mV al zeer goed staan en als het geheel is ingebouwd zal dit nog beter worden.
Dus daarom denk ik er aan om zeg iedere 0,25 Seconde een sampel te nemen, en dan te kijkne of deze sample anders is dan de vorige.
Dan heb ik alleen een knipperend display voor deze waarde als ik de uitgangspanning aan het instellen ben of dat de uitgang 1 digit verspringt door zeg ruis.

Ik heb er zover ik nu weet, alles aan gedaan om het display een zo mooi mogelijk resultaat te laten weergeven.
Alle vaste tekst waarbij het kan, staat in de setup van de code zoasl de kader, lijnen en wat tekst die dus niet veranderd.

De roep om HELP is, of jullie misschien een manier weten om het beter uit te voeren, zodat de uitgangsspanning minder knipperd?

Hier twee plaatjes en jammer genoeg geen filmpje om aan te geven hoe het er uit ziet.
Het eerste plaatje is net genomen op een moment dat de waarde van de ADS1115 overschrven is met een zwart vlak.
De streepjes in de blauwe vlakken zijn met het oog niet zichtbaar, dat is waarschijnlijk een alias probleem van de Sony camera.
http://www.bramcam.nl/NA/LowCostCal/LowCostCal-80.png

En nu is het opbouwen van de gemeten waarde bijna klaar, de comma staat er al en een heel klein stukje van het laatste cijfer.
De reeks wordt dus van links af opgebouwd en de snelheid is die van de loop en het aantal samples per seconde, het ziet er echt lelijk uit... :-(
http://www.bramcam.nl/NA/LowCostCal/LowCostCal-81.png

Dus...
weten jullie een beter oplossing?

Dank en groet,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"

Er blijft dan residu achter van de vorige waarde, dit los ik de ene keer op met het plaatsen van zeg een zwart of gekleurt vakje over de oude tekst,
dan schrijf ik daar dan weer de nieuwe tekst overheen.

Dat heeft niets met de verversing van het scherm zelf te maken maar gewoon met de library. Ik liep er met mijn oled display ook al tegenaan. Er word enkel bij gehouden of een pixel aan moet zijn maar niet of een pixel ook weer uit moet en daardoor blijft er een residu achter. Er eerst een lege waarde na toe sturen gaf bij mij hele nare flikkeringen. En heb dan maar voor elke nieuw tekst wijziging het hele dispaly geheugen gewist en opnieuw gaan schrijven.

Alle vaste tekst waarbij het kan, staat in de setup van de code zoasl de kader, lijnen en wat tekst die dus niet veranderd.

Daar het gaat dus fout in combinatie met de library. Ik kreeg een veel rustiger beeld (wel met een geheel ander scherm) door elke keer het display geheugen te wissen en dan opnieuw te schrijven. Bij mijn library zit het display geheugen in de arduino zelf en word alleen als een pixel aan moet zijn dit gewijzigd maar niet als het uit moet zijn. Bij de opdracht om de tekst op het display te tonen word het hele display buffer in de arduino in 1 keer naar het display geschreven.

Echter deze library die jij gebruikt ken ik verder niet maar lijkt dus wel op de achtergrond hetzelfde te werken.

[Bericht gewijzigd door benleentje op 27 december 2017 23:33:50 (35%)]

Hewlett

Honourable Member

Beste oplossing is double buffering, maar dat zal dit display wel niet kunnen. Zoals je zelf al aangeeft kun het heel wat verbeteren door alleen een update te doen wanneer de huidige gelezen ADC waarde anders is als de vorige welke op het display staat. Wellicht kun je hier nog een relatieve delta erbij betrekken, dus wanneer de nieuwe waarde minder dan een fractie anders is doe je geen update. Meestal zal het LSD alleen veranderen (ruis etc), je kunt ervoor kiezen om die verandering niet te laten zien. Denk ook dat je moet kijken om de blanking anders te doen, je moet nu met dat zwarte rechthoek een compleet pixel blok van de Arduino naar het paneel sturen, dat zal wat extra tijd kosten.

Andere, mogelijk snellere manier, is om de huidige waarde te overschrijven met zichzelf alleen dan in de achtergrond kleur. Kleine uitbreiding hierop; meestal zullen alleen de laatste minst significante digits veranderen, je bepaalt op welke positie de eerste verandering plaatvind en vanaf deze positie print je spaties, dus de huidige waarde wordt opnieuw geprint met alleen de delta gewist. Vervolgens print je de complete nieuwe waarde opnieuw, alleen nu wel met alle digits. Deze kleine aanpassing in het display algoritme zal je flikkering doen verminderen, denk ik ;-) want effectief wordt alleen de verandering opnieuw geprint.

Indien je een monospace (niet proportioneel) font neemt dan kun je de cijfers die niet veranderen opgemoeid laten en alleen de cijfers die anders zijn refreshen. Dat is sneller, maar wellicht is zo'n font minder mooi.

Waarom moet de display update zo snel zijn? Als je de ADC waarde elke seconde op het display print heb je dit knipper/refresh probleem ook minder.

edit en kleine toevoeging: Dat residu effect komt omdat je niet in de achtergrond kleur overscrhijft, maar in een transparante kleur. Je moet expliciet de achtergrond kleur opgeven.

HamRadio PA2HK // Keep Calm and Carry On.

Volgens mij heb je ook een Arduino DUE liggen, daar zou ik het ook eens mee proberen Bram. De 8 bitters icm grafische displays zijn geen snelheidsmonsters.

It's the rule that you live by and die for It's the one thing you can't deny Even though you don't know what the price is. It is justified.
blackdog

Golden Member

Hi Heren, :-)

benleentje, geprobeerd iedere keer het hele scherm te schrijven, dat is niet om aan te zien...
Daarom ben ik ook alle de vaste data, in de setup gaan zetten.

Hewlett,
De oude data overschrijven met zwarte text heb ik ook al gedaan om het verschil te kunnen zien als je een zwart blok gebruikt voor de zelfde functie.
Vooralsnog op het oog maakte het weinig uit.

Maar ik zal zeker een kijken of mijn achtergrond wel als basis, zwart is.
Of anders schrijf ik nog een stukje code met een andere tint voor de achtergrond van de gemeten ADC waarde en test daar mee, goede tip!

De rede dat ik het redelijk snel (2 tot 4 metingen per seconde) wil hebben, is het soepel instellen van de gewenste waarde.
De uitlezing is een extra stukje electronica als ook de display code, dit zat geheel niet in de opset van dit meetinstrument.
Maar ik weet b.v. nu, dat de ADS1115 goed bruikbaar is voor iets anders, wat hier nog op stapel staat.
Want de bedoeling van dit meetinstrument was, het samen met een 6,5 Digit meter of meer te gebruiken. :-)

Maar ik vind dit steeds leuker worden, en dan heb ik het over het programmeren...

Roland
Dat klopt en nog andere type microcontrolers ook, de hoeveelheid problemen wil je niet weten waar ik al tegenaan ben gelopen...
Dit werkt niet met dat, die library werkt weer niet met een Teensy enz, enz.
Ik heb het hier allemaal niet gemeld, maar ben er wel flink tegenaan gelopen!
Natuurlijk is dit met voldoende kennis van programmeren op te lossen, maar ik blijf vooralsnog een prutser wat programmeren betreft ;-)

Groet,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"

benleentje, geprobeerd iedere keer het hele scherm te schrijven, dat is niet om aan te zien...
Daarom ben ik ook alle de vaste data, in de setup gaan zetten.

Dan zie je maar weer dat elk display toch weer andere problemen geeft.

Maar het probleem blijft dan wel wat ik zij en dat is dat alleen gekeken word of een pixel geset moet worden. ALs je dan een andere kleur neemt dan zou die kleur een pixel aan moeten zetten die juist jouw oude pixel wist.

Ik ben helaas niet bekend met deze library dus kan je ook niet echt helpen.

Ik ken die library niet en ik heb ook geen display om te experimenteren, maar ik zie wel een paar dingen die niet optimaal zijn.

Je wilt zo weinig mogelijk veranderen op het scherm, zeker als je een relatief trage interface hebt. Eerst een zwart blok schrijven en daar dan later nieuwe text overschrijven is inderdaad lelijk, dus dat moet je niet doen.

Maar dan heb je last van residu, dus dan moet je dat aanpakken. De tekst funkties die je nu gebruikt schrijven nu alleen de letters en niet de achtergrond, zodat restanten van de letters blijven staan. Door een andere fontmode te kiezen wordt ook de achtergrond beschreven:

In setup :

code:


   ucg.setfontmode(UCG_FONT_MODE_SOLID);

Dan moet je trouwens wel kiezen voor een font dat werkt. De transparante fonts werken niet met UCG_FONT_MODE_SOLID.

Dan kun je 2 kleuren zetten voor text. De tekst kleur in index 0 en de achtergrond kleur in index 1:

code:


   ucg.setColor(0, 255, 255, 255);  // Wit voor de text 
   ucg.setColor(1,   0,   0,   0);  // Zwart voor de achtergrond

En dan blijft er nog het probleem met ucg.print. Met die funktie weet je niet hoeveel cijfers er geschreven gaan worden. Je wilt 1000.8, dus 4 cijfers, een punt en nog een cijfer. De ucg print funktie weet dat niet en daar kun je het aantal cijfers niet opgeven. Dus dan kun je beter eerst zelf een string aanmaken en dan die string naar het display schrijven.

code:


  char Buffer[10];
  dtostrf(1000.0F * ads.readADC_SingleEnded_V(0), 6, 1, Buffer);
  ucg.print(Buffer);

Als het goed is is het dan niet meer nodig om eerste en blackbox te schrijven om de oude text weg te halen.

blackdog

Golden Member

Hi,

Kijk dat zijn nu leuke berichten tijdens mijn lunch :-)

Als deKees gelijk heeft (ik vermoed het wel), dan zijn de trucs die ik al heb toegepast en waar Hewlett aanvullingen op gaf, niet meer nodig.
Zo gauw ik mij even kan losrukken van mijn bedrijfs-administratie ga ik de voorstellen van deKees testen.

Mijn dank is alvast groot.

Groet,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"
blackdog

Golden Member

Hi,

Net het Administratieve bijltje even neergegooid..

En ik vond dat ik hierna wel even aan de electronica mocht werken *grin*

deKees, je bent mijn HELD voor vanavond!!!
Je opmerking was helemaal goed betreffende de fontmodus van de Ucglib library.

Ook deze truc werkt al eeen zonnetje: char Buffer[10];

Moi, is happy na een frustrerende administratie dag :-)

Groet,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"
blackdog

Golden Member

Hi,

Nu werd ik overmoedig en probeerde de zelfde truc ook uit te halen bij de temperatuur meting...
Iets beneden het midden onder de spatie heb ik "char celsius" gebruikt.

c code:


// Start to measure temperature
  currentTime = millis();
  if(currentTime >= (loopTime + 5000)){              // Every 5 second sample temperature
  ucg.setFont(ucg_font_courB12_tf);                  // Set font type
  ucg.setFontMode(UCG_FONT_MODE_SOLID);
  ucg.setColor(255, 255, 255);                       // Font color
  ucg.setColor(1, 0, 0, 0);                          // Background color 
  ucg.setPrintPos(58,17);                            // Set position "wipe out" text
  ucg.print(oldTemp);                                // Overwrite old temperature value with black fonts
  ucg.setColor(0, 255, 255, 255);                    // Switch color to white  
  sensor.shutdown(false);                            // Switch on SE95 temp sensor

  char celsius[10];
  celsius = (sensor.temp());                         // Put temperature in celsius variable
  ucg.setPrintPos(58,17);                            // Set position for writing new temperature value
  ucg.print(celsius);                                // Place measured temperature on the screen
  sensor.shutdown(true);                             // Switch off SE95 sensor
  oldTemp = celsius;                                 // Updates oldTemp 
  loopTime = currentTime;                            // Update loopTime
  }
  else
// End measure temperature

Waarschijnlijk ben ik te gaar om dit nu te begijpen, maar dit is in ieder geval een stukje error code van de Arduino IDE:

Button-Bipolaire-Driver-25:184: error: incompatible types in assignment of 'float' to 'char [10]'

celsius = (sensor.temp()); // Put temperature in celsius variable

Ik zie niet direct het verschil met de eigenschappen van de variabele die uit de ADS1115 komt.

Gaarne schopje in de goede richting :-)

Groet,
Bram

Waarheden zijn "Illusies waarvan men vergeten is dat het illusies zijn"

celsius is een char array, en sensor.temp() geeft een float. Die kun je niet zomaar met een = aan elkaar koppelen, dus daar moet je weer de conversie funktie voor gebruiken:

code:


   ... 
   dtostrf(sensor.temp(), 6, 2, celsius);
   ucg.print(celcius);
   ... 

Of misschien met andere parameters? Je krijgt nu 6 letters totaal, met 2 cijfers achter de komma, als in " 25.50".