[Solved] Standard LCD-Routines not working

Generic boards that are not Maple or Maple mini clones, and don't contain the additional USB reset hardware
Locked
User avatar
lsmod
Posts: 65
Joined: Mon Dec 24, 2018 4:36 pm
Location: Germany

[Solved] Standard LCD-Routines not working

Post by lsmod » Wed Jan 09, 2019 1:10 pm

I just want to connect a simple LCD-Display in an standard way to an blue pill board.

The LCD is tested with an AVR and it is working.
But it is dead connected to the blue pill board.
It makes no difference if an 4 or 8 bit bus for the LCD is being used.

Code: Select all

#include 
// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
LiquidCrystal lcd(PB4, PB5, PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7);
void blink() {
  digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
void setup() {
  delay(100);
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("hello, world!");
  lcd.setCursor(0, 1);
  lcd.print("hello second line!");
  pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
  // scroll 13 positions (string length) to the left
  // to move it offscreen left:
  for (int positionCounter = 0; positionCounter < 13; positionCounter++) {
    // scroll one position left:
    lcd.scrollDisplayLeft();
    // wait a bit:
    delay(150);
  }
  blink();
  // scroll 29 positions (string length + display length) to the right
  // to move it offscreen right:
  for (int positionCounter = 0; positionCounter < 29; positionCounter++) {
    // scroll one position right:
    lcd.scrollDisplayRight();
    // wait a bit:
    delay(150);
  }
  blink();
  // scroll 16 positions (display length + string length) to the left
  // to move it back to center:
  for (int positionCounter = 0; positionCounter < 16; positionCounter++) {
    // scroll one position left:
    lcd.scrollDisplayLeft();
    // wait a bit:
    delay(150);
  }
  blink();
}
The compiler says
/home/me/.arduino15/packages/stm32duino/hardware/STM32F1/2018.12.3/libraries/LiquidCrystal (legacy) is used.
This should be the correct one.

When i measure for signals with an oscilloscope all signals for the LCD are dead!
Some are high (like rs), some are low (like en), but there is no change and data.

Any ideas?
Last edited by lsmod on Sat Jan 12, 2019 3:21 pm, edited 2 times in total.

User avatar
BennehBoy
Posts: 886
Joined: Thu Jan 05, 2017 8:21 pm
Location: Yorkshire
Contact:

Re: Standard LCD-Routines not working

Post by BennehBoy » Wed Jan 09, 2019 1:48 pm

How have you powered the LCD, they don't like 3.3V
-------------------------------------
https://github.com/BennehBoy

User avatar
lsmod
Posts: 65
Joined: Mon Dec 24, 2018 4:36 pm
Location: Germany

Re: Standard LCD-Routines not working

Post by lsmod » Wed Jan 09, 2019 2:32 pm

It's powered with 5V.
Maybe i test it with 3.3V when it is running with 5V.

User avatar
BennehBoy
Posts: 886
Joined: Thu Jan 05, 2017 8:21 pm
Location: Yorkshire
Contact:

Re: Standard LCD-Routines not working

Post by BennehBoy » Wed Jan 09, 2019 2:38 pm

FWIW I always use i2C driven LCD (hardware driver adapter), and LiquidCrystal-i2c standard Arduino lib...
-------------------------------------
https://github.com/BennehBoy

User avatar
lsmod
Posts: 65
Joined: Mon Dec 24, 2018 4:36 pm
Location: Germany

Re: Standard LCD-Routines not working

Post by lsmod » Wed Jan 09, 2019 2:46 pm

Yes - i have seen the threads that I2C should work.
So the standard library for LCD is broken?

I want to adress an AD9850 parallel over an 8 Bit bus, so it is needed anyway. ;)

User avatar
BennehBoy
Posts: 886
Joined: Thu Jan 05, 2017 8:21 pm
Location: Yorkshire
Contact:

Re: Standard LCD-Routines not working

Post by BennehBoy » Wed Jan 09, 2019 2:51 pm

Unknown - it's not something that I've tried.

Fingers crossed a more experienced forum member comments.
-------------------------------------
https://github.com/BennehBoy

User avatar
lsmod
Posts: 65
Joined: Mon Dec 24, 2018 4:36 pm
Location: Germany

Re: Standard LCD-Routines not working

Post by lsmod » Wed Jan 09, 2019 5:04 pm

It seems that the library stuff has been compiled and added to the binary:

Code: Select all

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
LiquidCrystal lcd(PB4, PB5, PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7);
 80001f6:	2102      	movs	r1, #2
 80001f8:	2203      	movs	r2, #3
 80001fa:	2304      	movs	r3, #4
 80001fc:	e88d 000f 	stmia.w	sp, {r0, r1, r2, r3}
 8000200:	2305      	movs	r3, #5
 8000202:	9304      	str	r3, [sp, #16]
 8000204:	2306      	movs	r3, #6
 8000206:	9305      	str	r3, [sp, #20]
 8000208:	2307      	movs	r3, #7
 800020a:	9306      	str	r3, [sp, #24]
 800020c:	2114      	movs	r1, #20
 800020e:	2215      	movs	r2, #21
 8000210:	2300      	movs	r3, #0
 8000212:	4803      	ldr	r0, [pc, #12]	; (8000220 <_GLOBAL__sub_I_lcd+0x30>)
 8000214:	f000 f806 	bl	8000224 <_ZN13LiquidCrystalC1Ehhhhhhhhhh>
    lcd.scrollDisplayLeft();
    // wait a bit:
    delay(150);
  }
  blink();
  LiquidCrystal::LiquidCrystal(uint8 rs, uint8 enable,
                             uint8 d0, uint8 d1, uint8 d2, uint8 d3,
                             uint8 d4, uint8 d5, uint8 d6, uint8 d7)
 800022c:	4e0f      	ldr	r6, [pc, #60]	; (800026c <_ZN13LiquidCrystalC1Ehhhhhhhhhh+0x48>)
  _rs_pin = rs;
  _rw_pin = rw;
  _enable_pin = enable;
  _data_pins[0] = d0;
  _data_pins[1] = d1;
 800022e:	7343      	strb	r3, [r0, #13]
  _data_pins[2] = d2;
 8000230:	f89d 3014 	ldrb.w	r3, [sp, #20]
    size_t println(const Printable&);
#ifdef SUPPORTS_PRINTF
// Roger Clark. Work in progress to add printf support
	int printf(const char * format, ...);
#endif
    Print() : write_error(0) {}
 8000234:	2500      	movs	r5, #0
 8000236:	7383      	strb	r3, [r0, #14]
  _data_pins[3] = d3;
 8000238:	f89d 3018 	ldrb.w	r3, [sp, #24]
}
With real machine code to access the GPIO ports?

Code: Select all

inline void LiquidCrystal::command(uint8 value) {
  send(value, LOW);
}
inline size_t LiquidCrystal::write(uint8 value) {
 80004e6:	b508      	push	{r3, lr}
  send(value, HIGH);
 80004e8:	2201      	movs	r2, #1
 80004ea:	f7ff ff13 	bl	8000314 <_ZN13LiquidCrystal4sendEhh>
    return 1;
}
 80004ee:	2001      	movs	r0, #1
 80004f0:	bd08      	pop	{r3, pc}
 /************ low level data pushing commands **********/
// write either command or data, with automatic 4/8-bit selection
void LiquidCrystal::send(uint8 value, uint8 mode) {
 8000314:	b538      	push	{r3, r4, r5, lr}
 8000316:	4604      	mov	r4, r0
 8000318:	460d      	mov	r5, r1
  digitalWrite(_rs_pin, mode);
 800031a:	7a40      	ldrb	r0, [r0, #9]
 800031c:	4611      	mov	r1, r2
 800031e:	f002 f8a9 	bl	8002474 <_Z12digitalWritehh>
  // if there is a RW pin indicated, set it low to Write
  if (_rw_pin != 255) {
 8000322:	7aa0      	ldrb	r0, [r4, #10]
 8000324:	28ff      	cmp	r0, #255	; 0xff
 8000326:	d002      	beq.n	800032e <_ZN13LiquidCrystal4sendEhh+0x1a>
    digitalWrite(_rw_pin, LOW);
 8000328:	2100      	movs	r1, #0
 800032a:	f002 f8a3 	bl	8002474 <_Z12digitalWritehh>
  }
  if (_displayfunction & LCD_8BITMODE) {
 800032e:	7d23      	ldrb	r3, [r4, #20]
    write8bits(value);
 8000330:	4620      	mov	r0, r4
  // if there is a RW pin indicated, set it low to Write
  if (_rw_pin != 255) {
    digitalWrite(_rw_pin, LOW);
  }
  if (_displayfunction & LCD_8BITMODE) {
 8000332:	06db      	lsls	r3, r3, #27
 8000334:	d504      	bpl.n	8000340 <_ZN13LiquidCrystal4sendEhh+0x2c>
    write8bits(value);
 8000336:	4629      	mov	r1, r5
  } else {
    write4bits(value>>4);
    write4bits(value);
  }
}
 8000338:	e8bd 4038 	ldmia.w	sp!, {r3, r4, r5, lr}
  if (_rw_pin != 255) {
    digitalWrite(_rw_pin, LOW);
  }
  if (_displayfunction & LCD_8BITMODE) {
    write8bits(value);
 800033c:	f7ff bfd6 	b.w	80002ec <_ZN13LiquidCrystal10write8bitsEh>
  } else {
    write4bits(value>>4);
 8000340:	0929      	lsrs	r1, r5, #4
 8000342:	f7ff ffbf 	bl	80002c4 <_ZN13LiquidCrystal10write4bitsEh>
    write4bits(value);
 8000346:	4620      	mov	r0, r4
 8000348:	4629      	mov	r1, r5
  }
}
 800034a:	e8bd 4038 	ldmia.w	sp!, {r3, r4, r5, lr}
  if (_displayfunction & LCD_8BITMODE) {
    write8bits(value);
  } else {
    write4bits(value>>4);
    write4bits(value);
 800034e:	f7ff bfb9 	b.w	80002c4 <_ZN13LiquidCrystal10write4bitsEh>
08000352 <_ZN13LiquidCrystal7commandEh>:
}

User avatar
mrburnette
Posts: 3001
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: Standard LCD-Routines not working

Post by mrburnette » Wed Jan 09, 2019 5:17 pm

Maybe take a look at this LCD implementation:

http://stm32duinoforum.com/forum/viewtopic.php?t=1171

User avatar
lsmod
Posts: 65
Joined: Mon Dec 24, 2018 4:36 pm
Location: Germany

Re: Standard LCD-Routines not working

Post by lsmod » Wed Jan 09, 2019 5:56 pm

I altered the pins, compiled and uploaded it, but the display is still dead.
I can check the physical signals, but i would say it is the same reason.
This example is from the middle of 2016 ...

Code: Select all

#include 
// HW definitions
#define LED     PC13    // Maple-mini LED
#define BUT     PB8     // Maple-mini BUT pushbutton
#define LCD_RS  PB4
#define LCD_E   PB5
#define LCD_D4  PA4
#define LCD_D5  PA5
#define LCD_D6  PA6
#define LCD_D7  PB7
#define LCD_LED PB6     // LCD backlight led
#define LCD_V0  PA8     // LCD contrast voltage (PWM generated)
enum LcdModel {LCD2004, LCD1602};
const   uint16_t  maxPWM = 0xFFFF;        // Max value (hex) for PWM (see datasheet)
const   uint16_t  contrast = maxPWM/3;    // 33% duty cycle should be a good "default" value (V0 = Vdd/3 = 1.1V)
const   uint16_t  bklight = 0;            // 0 means full bright backlight
const   LcdModel  Lcd = LCD1602;          // LCD module type (2004 or 1602)
LiquidCrystal     lcd(LCD_RS, LCD_E, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
uint32_t          i;
boolean           flag = 0;
void setup() 
{
  // Initaialize LED and BUT button
  pinMode(LED, OUTPUT);
  pinMode(BUT, INPUT);
  // Wait until BUT is pressed
  digitalWrite(LED, HIGH);
  while(!digitalRead(BUT)) {}   
  digitalWrite(LED, LOW);
  // Initialize LCD and the two used PWMs (for contrast and backlight)
  lcd.begin(16, 2);
  pinMode(LCD_V0, PWM);
  pinMode(LCD_LED, PWM_OPEN_DRAIN);   // This one must be "open drain" output
  pwmWrite(LCD_V0, contrast);
  pwmWrite(LCD_LED, bklight);
}
void loop() 
{
  // Display titles
  if (Lcd == LCD2004)
  {
    lcd.print("  ARM STM32F103C8");
    lcd.setCursor(0, 1);
    lcd.print("     LCD Demo");
    delay(3000);
    lcd.clear();
    lcd.print("    Powered by:");
    lcd.setCursor(0, 1);
    lcd.print(" stm32duinoforum.com/forum");
  }
  else
  {
    lcd.print("   STM32F103C8");
    lcd.setCursor(0, 1);
    lcd.print("    LCD Demo");
    delay(3000);
    lcd.clear();
    lcd.print("   Powered by:");
    lcd.setCursor(0, 1);
    lcd.print(" stm32duinoforum.com/forum");
  }
  delay(3000);
  // Contrast demo
  for (i = 1; i <= 4; i++)
  {
    if (Lcd == LCD2004)
    {
      lcd.setCursor(0, 2);
      lcd.print("                 ");
      delay(500);
      lcd.setCursor(0, 2);
      lcd.print("   -> Contrast <-");
    }
    else
    {
      lcd.clear();
      //lcd.setCursor(0, 1);
      //lcd.print("              ");
      delay(500);
      //lcd.setCursor(0, );
      lcd.print(" -> Contrast <-");
    }
      delay(500);
  }
  for (i = 0; i <= maxPWM; i = i+40)
  {
    pwmWrite(LCD_V0, i);
    delay(10);
    if (Lcd == LCD2004)
    {
      lcd.setCursor(0, 3);
      lcd.print("  PWM level: ");
    }
    else
    {
      lcd.setCursor(0, 1);
      lcd.print("PWM level: ");
    }
    lcd.print(i);
  } 
  for (i = 0; i <= maxPWM; i = i+40)
  {
  lcd.setCursor(0, 2);
  lcd.print("                 ");
  lcd.setCursor(0, 3);
  lcd.print("                  ");
  }
  pwmWrite(LCD_V0, contrast);
  // Backlight demo
  for (i = 1; i <= 4; i++)
  {
    if (Lcd == LCD2004)
    {
      lcd.setCursor(0, 2);
      lcd.print("                  ");
      delay(500);
      lcd.setCursor(0, 2);
      lcd.print("  ->  Backlight <-");
    }
    else
    {
      lcd.clear();
      //lcd.setCursor(0, 0);
      //lcd.print("             ");
      delay(500);
      //lcd.setCursor(0, 1);
      lcd.print(" -> Backlight <-");
    }
      delay(500);    
  }
  for (i = 0; i <= maxPWM; i = i+40)
  {
    pwmWrite(LCD_LED, i);
    delay(10);
    if (Lcd == LCD2004)
    {
      lcd.setCursor(0, 3);
      lcd.print("  PWM level: ");
    }
    else
    {
      lcd.setCursor(0, 1);
      lcd.print("PWM level: ");
    }
    lcd.print(i);
  } 
  // Final greetings
  lcd.clear();
  delay(1000);
  pwmWrite(LCD_LED, bklight);
  lcd.setCursor(0, 1);
  if (Lcd == LCD2004) {lcd.print("  ");};
  lcd.print("   - bye... -");
  for (i = 1; i <= 6; i++)
  {
    delay(500);
    pwmWrite(LCD_LED, flag * maxPWM);
    flag = !flag;
  }
  lcd.clear();
  // Wait until BUT is pressed to run an other loop
  digitalWrite(LED, HIGH);
  while(!digitalRead(BUT)) {}
  digitalWrite(LED, LOW);
  pwmWrite(LCD_LED, bklight);
}
But i like the idea of using PWM for the display contrast.
I have made some designs with AVR where i can say that i don't need any resistor or capacitor.
Just give direct the PWM to V0 and you can regulate the contrast.

User avatar
lsmod
Posts: 65
Joined: Mon Dec 24, 2018 4:36 pm
Location: Germany

Re: Standard LCD-Routines not working

Post by lsmod » Sat Jan 12, 2019 3:19 pm

The problem could be solved here viewtopic.php?f=45&t=4301&p=52373#p52371

In the setup was missing:

Code: Select all

enableDebugPorts();

Locked