Custom characters

Hallo.

Ik ben bezig om een voorversterker te maken met een pga2311 en lcd display, diverse relais gestuurde ingangen en aangestuurde met een arduino.
Arduino is voor mij helemaal nieuw, ik heb uit enkele bestaande sketches al iets in elkaar kunnen zetten waardoor de IR-remote en de rotary encoder inmiddels al redelijk werken met de dB waarden op het display.
Het display wordt via I2c aangesloten en uiteraard de PGA via SPI.
Nu heb ik een probleem, ik krijg geen custom karakters op het display voor de volume bar, de normale teksten zij er wel gewoon.
De blokken worden volledig, wel netjes oplopend met de volume instelling, gevuld met 1 vreemd karakter.
ik heb een gedeelte van deze sketch gebruikt, alleen is het display hier normaal parallel aangesloten.

Of is er misschien iemand die zoiets al eens helemaal heeft uitgewerkt, en daarvan software wil afstaan, er staat heel veel op internet hierover, maar eigenlijk nergens software van een kompleet
geheel.

Groeten Hardy

Hoi Hardy.

Je hebt wel aangegeven hoe jouw voorbeeld was aangesloten, maar niet hoe jouw I2C oplossing met de display is verbonden.
Is pin 4 van jouw LCD ook met de I2C chip verbonden, en weet de sketch ook hoe het verbonden is ?

Laat je sketch ff zien. Dan kunnen we meedenken.

In het lcd zitten een paar karakters die je aan kunt passen, kijk eerst eens of het er tussen zit wat je zoekt, in de datasheet staat dat.
maar helaas heb je niets verteld dus is het gokken voor ons.

Bedank alvast voor de reacties, sketch komt eraan, wordt alleen vanavond pas.

Hardy

Hierbij mij sketch en foto’s van hoe mijn display het weergeeft.
Er zal misschien ook wel rommel instaan die anders of eruit kunnen, is veel plak en knipwerk van uit bestaande codes

(upload://6I6PuuEmauXO02up6hgyYXrei26.jpeg)]

#include <stdlib.h>
#include <IRremote.h>
#include <SPI.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include "SPI.h"

LiquidCrystal_I2C lcd(0x20, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

const int slaveSelectPin = 10;
int RECV_PIN = 4;
IRrecv irrecv(RECV_PIN);
decode_results results;

const int PGA_CS_PIN = 10;
const int PGA_SCLK_PIN = 13;
const int PGA_SDI_PIN = 11;
int state, prevstate, volumeLevel, level = 0;
int nextEncoderState[4] = { 2, 0, 3, 1 };
int prevEncoderState[4] = { 1, 3, 0, 2 };

char cGain [17];
String gain;
char icGain[6];
float iGain = -95.5;
float nGain = 1;

boolean mute = false;
// custom LCD characters for the volume bar
byte v0[8] = {B00000,B00000,B00000,B00000,B00000,B00000,B00000};
byte v1[8] = {B00000,B00000,B00000,B00000,B00000,B00000,B11111};
byte v2[8] = {B00000,B00000,B00000,B00000,B00000,B11111,B11111};
byte v3[8] = {B00000,B00000,B00000,B00000,B11111,B11111,B11111};
byte v4[8] = {B00000,B00000,B00000,B11111,B11111,B11111,B11111};
byte v5[8] = {B00000,B00000,B11111,B11111,B11111,B11111,B11111};
byte v6[8] = {B00000,B11111,B11111,B11111,B11111,B11111,B11111};
byte v7[8] = {B11111,B11111,B11111,B11111,B11111,B11111,B11111};

void setup() {
 lcd.createChar(0, v0);
 lcd.createChar(1, v1);
 lcd.createChar(2, v2);
 lcd.createChar(3, v3);
 lcd.createChar(4, v4);
 lcd.createChar(5, v5);
 lcd.createChar(6, v6);
 lcd.createChar(7, v7);
 lcd.begin(16, 2);

pinMode(PGA_CS_PIN,OUTPUT);
pinMode(PGA_SCLK_PIN,OUTPUT);
pinMode(PGA_SDI_PIN,OUTPUT);
digitalWrite(PGA_CS_PIN,HIGH);
digitalWrite(PGA_SCLK_PIN,HIGH);
digitalWrite(PGA_SDI_PIN,HIGH);
pinMode(5, INPUT);
pinMode(6, OUTPUT);
pinMode(7, INPUT);
digitalWrite(5, HIGH);
digitalWrite(6, LOW);
digitalWrite(7, HIGH);
Serial.begin(9600);

 lcd.write(" HiFi IR Volume ");
 
 irrecv.enableIRIn();
 
 pinMode(slaveSelectPin, OUTPUT);
 SPI.begin(); 
 setGain(1);

}

void decodeIR(int value) {
 switch (value) {
 case 0x40a:
   mute = !mute;
   lcd.setCursor(0, 0);
   if (mute == true) {
     lcd.write("        Muted        ");
     setGain(1);
   }
   if (mute == false) {  
     setGain(nGain);
     setVolumeBar(nGain);
   }
   delay(1000);
   break;
 case 0xc11:
   if (nGain < 255) {  
     nGain = nGain + 1;
     setGain(nGain);
     setVolumeBar(nGain);
   }
   else {
     lcd.setCursor(0, 0);
     lcd.write("Maximum Reached");
     delay(500);
   }  
   break;
 case 0x410:
   if (nGain > 1) {
     nGain = nGain - 1;
     setGain(nGain);
     setVolumeBar(nGain);
   }
   else {
     lcd.setCursor(0,0);
     lcd.write("Minimum Reached ");
     delay(500);     
   }
   break;
 }
 
}

void setGain(int nGain) {
 digitalWrite(slaveSelectPin,LOW);
 SPI.transfer(nGain);  // right channel
 SPI.transfer(nGain);  // left channel
 digitalWrite(slaveSelectPin,HIGH);
}

void setVolumeBar(int nGain) {
 // convert gain to a decibal string, and write to the lcd
 iGain = 31.5 - 0.5*(255 - float(nGain));       
 gain.toCharArray(icGain, 6);
 dtostrf(iGain,4,1,icGain);
 gain = String(icGain);
 lcd.clear();
 ("Volume: " + gain + " dB").toCharArray(cGain,17);
 lcd.setCursor(0, 0);  //first line
 lcd.write(cGain);
 // write the volume bar
 lcd.setCursor(0, 1);  //second line
 for (int i =  0; i < 16; i++) {
   if (nGain/2 > i*8) {
     lcd.setCursor(i, 1);
     lcd.write(round(i/2));
   }
 }
}

void loop(){
 // receive an IR signal
 if (irrecv.decode(&results)) {
   decodeIR(results.value);
   irrecv.resume();
 }

  state = (digitalRead(7) << 1) | digitalRead(5);
  if (state != prevstate) {
  if (state == nextEncoderState[prevstate]) {
    if (nGain < 255) {
      nGain = nGain + 1;
      setGain(nGain);
      setVolumeBar(nGain);
      Serial.println(nGain, DEC);
    }
  } else if (state == prevEncoderState[prevstate]) {
   
    if (nGain > 0) {
      nGain = nGain - 1;
      setGain(nGain);
      setVolumeBar(nGain);
      Serial.println(nGain, DEC);
    }
  }
  prevstate = state;
}
}

Een paar dingen die mij opvallen tussen jouw sketch en dit voorbeeld: Custom characters on LCD 1602 screen with I2C interface | Facelesstech
is dat:
a) jij maar 7 bytes invult in een array van 8
b) Je eerst de createChar doet en daarna pas begin(). Volgens mij moet dat net andersom.

Bedankt Nico !

Dat krijg je met copy/paste van een bestaande sketch :slight_smile: , maar dat "begin()" had ik ook al gezien, maar nog niet veranderd, omdat ik er even vanuit ging dat dit een werkende sketch zou zijn.
Ik ga dit vanavond direct testen.
Dat van die 7 bytes was mij nog niet opgevallen, maar zal ik ook proberen.

Groeten Hardy

Hallo Nico.

Ik heb even verder gekeken op die link die je erbij gezet hebt, maar hier doen ze precies hetzelfde, dus ik snap er toch nog niet zoveel van nu.

https://www.arduino.cc/en/Reference/LiquidCrystalCreateChar

Hardy

Heb je die sketch die daar staat gewoon eens geprobeerd?

wordt allemaal weer vanavond geprobeerd.

Nou ik heb ff jouw sketch gepakt en hier een daar een beetje aan gesleuteld (veel in commentaar) en wat aanpassingen. met mijn library. En dit werkte goed:

#include <stdlib.h>
//#include <IRremote.h>
//#include <SPI.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//#include "SPI.h"

//LiquidCrystal_I2C lcd(0x20, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address
LiquidCrystal_I2C lcd(0x27, 2, 16);  // Set the LCD I2C address

//const int slaveSelectPin = 10;
//int RECV_PIN = 4;
//IRrecv irrecv(RECV_PIN);
//decode_results results;
//
//const int PGA_CS_PIN = 10;
//const int PGA_SCLK_PIN = 13;
//const int PGA_SDI_PIN = 11;
//int state, prevstate, volumeLevel, level = 0;
//int nextEncoderState[4] = { 2, 0, 3, 1 };
//int prevEncoderState[4] = { 1, 3, 0, 2 };
//
char cGain [17];
String gain;
char icGain[6];
float iGain = -95.5;
float nGain = 1;
//
//boolean mute = false;
// custom LCD characters for the volume bar
byte v0[8] = { B00000, B00000, B00000, B00000, B00000, B00000, B00000 };
byte v1[8] = { B00000, B00000, B00000, B00000, B00000, B00000, B11111 };
byte v2[8] = { B00000, B00000, B00000, B00000, B00000, B11111, B11111 };
byte v3[8] = { B00000, B00000, B00000, B00000, B11111, B11111, B11111 };
byte v4[8] = { B00000, B00000, B00000, B11111, B11111, B11111, B11111 };
byte v5[8] = { B00000, B00000, B11111, B11111, B11111, B11111, B11111 };
byte v6[8] = { B00000, B11111, B11111, B11111, B11111, B11111, B11111 };
byte v7[8] = { B11111, B11111, B11111, B11111, B11111, B11111, B11111 };

void setup() {
	lcd.init();
	lcd.backlight();
	lcd.createChar(0, v0);
	lcd.createChar(1, v1);
	lcd.createChar(2, v2);
	lcd.createChar(3, v3);
	lcd.createChar(4, v4);
	lcd.createChar(5, v5);
	lcd.createChar(6, v6);
	lcd.createChar(7, v7);

// lcd.begin(16, 2);

//	pinMode(PGA_CS_PIN, OUTPUT);
//	pinMode(PGA_SCLK_PIN, OUTPUT);
//	pinMode(PGA_SDI_PIN, OUTPUT);
//	digitalWrite(PGA_CS_PIN, HIGH);
//	digitalWrite(PGA_SCLK_PIN, HIGH);
//	digitalWrite(PGA_SDI_PIN, HIGH);
//	pinMode(5, INPUT);
//	pinMode(6, OUTPUT);
//	pinMode(7, INPUT);
//	digitalWrite(5, HIGH);
//	digitalWrite(6, LOW);
//	digitalWrite(7, HIGH);
//	Serial.begin(9600);

//	lcd.write(" HiFi IR Volume ");
	lcd.setCursor(0,0);
	lcd.print(" HiFi IR Volume ");

//	irrecv.enableIRIn();
//
//	pinMode(slaveSelectPin, OUTPUT);
//	SPI.begin();
//	setGain(1);
//
}

//void decodeIR(int value) {
//	switch (value) {
//	case 0x40a:
//		mute = !mute;
//		lcd.setCursor(0, 0);
//		if (mute == true) {
//			lcd.write("        Muted        ");
//			setGain(1);
//		}
//		if (mute == false) {
//			setGain (nGain);
//			setVolumeBar(nGain);
//		}
//		delay(1000);
//		break;
//	case 0xc11:
//		if (nGain < 255) {
//			nGain = nGain + 1;
//			setGain (nGain);
//			setVolumeBar(nGain);
//		} else {
//			lcd.setCursor(0, 0);
//			lcd.write("Maximum Reached");
//			delay(500);
//		}
//		break;
//	case 0x410:
//		if (nGain > 1) {
//			nGain = nGain - 1;
//			setGain (nGain);
//			setVolumeBar(nGain);
//		} else {
//			lcd.setCursor(0, 0);
//			lcd.write("Minimum Reached ");
//			delay(500);
//		}
//		break;
//	}
//
//}
//
//void setGain(int nGain) {
//	digitalWrite(slaveSelectPin, LOW);
//	SPI.transfer(nGain);  // right channel
//	SPI.transfer(nGain);  // left channel
//	digitalWrite(slaveSelectPin, HIGH);
//}

void setVolumeBar(int nGain) {
	// convert gain to a decibal string, and write to the lcd
	iGain = 31.5 - 0.5 * (255 - float(nGain));
	gain.toCharArray(icGain, 6);
	dtostrf(iGain, 4, 1, icGain);
	gain = String(icGain);
	lcd.clear();
	("Volume: " + gain + " dB").toCharArray(cGain, 17);
	lcd.setCursor(0, 0);  //first line
//	lcd.Write(cGain);
	lcd.print(cGain);
	// write the volume bar
	lcd.setCursor(0, 1);  //second line
	for (int i = 0; i < 16; i++) {
		if (nGain / 2 > i * 8) {
			lcd.setCursor(i, 1);
			lcd.write(round(i / 2));
		}
	}
}

void loop() {
	//
	// ff eigen volume test
	//
	for (uint16_t i = 60; i < 255; i=i+5){
		setVolumeBar(i);
		delay(250);
	}
	// receive an IR signal
//	if (irrecv.decode(&results)) {
//		decodeIR(results.value);
//		irrecv.resume();
//	}
//
//	state = (digitalRead(7) << 1) | digitalRead(5);
//	if (state != prevstate) {
//		if (state == nextEncoderState[prevstate]) {
//			if (nGain < 255) {
//				nGain = nGain + 1;
//				setGain (nGain);
//				setVolumeBar(nGain);
//				Serial.println(nGain, DEC);
//			}
//		} else if (state == prevEncoderState[prevstate]) {
//
//			if (nGain > 0) {
//				nGain = nGain - 1;
//				setGain (nGain);
//				setVolumeBar(nGain);
//				Serial.println(nGain, DEC);
//			}
//		}
//		prevstate = state;
//	}
}

Hij laat keurig het scherm zien en een oplopende en ophogende balk.
Tevens mijn I2C lib toegevoegd die ik gebruik (daar is gelijk de correctie ingebouwd bij een IDE hoger dan 1.6.5 waardoor hij anders alleen het eerste teken toont).

LiquidCrystal_I2C.zip (1.21 MB)

Nico Bedankt !

Ik ga er vanavond snel even naar kijken, en dat het misschien in een verkeerd library zou zitten had ik ook al vermoed, maar ik heb er verschillende geprobeerd, zonder succes.
Ik laat het wel weten hoe het gaat.

Hardy

Het werkt nu !!

Kom ik dus zelf nooit achter, wel fijn zo'n forum.
Kan ik weer een stukje verder, wie weet kom ik nog wel weer met vragen.
i.i.g. nogmaals bedankt.

Hardy