mirror of
				https://github.com/co-dan/ocaml-wiringpi/
				synced 2025-11-03 22:23:51 +01:00 
			
		
		
		
	Adafruit LCD example
This commit is contained in:
		
							
								
								
									
										6
									
								
								_oasis
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								_oasis
									
									
									
									
									
								
							@@ -18,3 +18,9 @@ Executable "wpi-button-example"
 | 
				
			|||||||
  BuildTools:   ocamlbuild
 | 
					  BuildTools:   ocamlbuild
 | 
				
			||||||
  MainIs:       button.ml
 | 
					  MainIs:       button.ml
 | 
				
			||||||
  BuildDepends: WiringPi,unix
 | 
					  BuildDepends: WiringPi,unix
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Executable "adafruit-lcd-example"
 | 
				
			||||||
 | 
					  Path:         examples/
 | 
				
			||||||
 | 
					  BuildTools:   ocamlbuild
 | 
				
			||||||
 | 
					  MainIs:       lcd.ml
 | 
				
			||||||
 | 
					  BuildDepends: WiringPi,unix
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										139
									
								
								examples/lcd.ml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								examples/lcd.ml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,139 @@
 | 
				
			|||||||
 | 
					(** An example with Adafruit character LCD, HD44780. *)
 | 
				
			||||||
 | 
					open Gpio3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(** Parameters *)
 | 
				
			||||||
 | 
					type mono_lcd = {
 | 
				
			||||||
 | 
					    columns: int;
 | 
				
			||||||
 | 
					    rows: int;
 | 
				
			||||||
 | 
					    rs: pin;
 | 
				
			||||||
 | 
					    en: pin;
 | 
				
			||||||
 | 
					    d4: pin;
 | 
				
			||||||
 | 
					    d5: pin;
 | 
				
			||||||
 | 
					    d6: pin;
 | 
				
			||||||
 | 
					    d7: pin
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					let lcd = {
 | 
				
			||||||
 | 
					    columns = 16;
 | 
				
			||||||
 | 
					    rows = 2;
 | 
				
			||||||
 | 
					    rs = GPIO20;
 | 
				
			||||||
 | 
					    en = GPIO16;
 | 
				
			||||||
 | 
					    d4 = GPIO19;
 | 
				
			||||||
 | 
					    d5 = GPIO5;
 | 
				
			||||||
 | 
					    d6 = GPIO11;
 | 
				
			||||||
 | 
					    d7 = GPIO10;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(** MAGIC NUMBERS *)
 | 
				
			||||||
 | 
					(* Commands *)
 | 
				
			||||||
 | 
					let _lcd_cleardisplay        = (0x01)
 | 
				
			||||||
 | 
					let _lcd_returnhome          = (0x02)
 | 
				
			||||||
 | 
					let _lcd_entrymodeset        = (0x04)
 | 
				
			||||||
 | 
					let _lcd_displaycontrol      = (0x08)
 | 
				
			||||||
 | 
					let _lcd_cursorshift         = (0x10)
 | 
				
			||||||
 | 
					let _lcd_functionset         = (0x20)
 | 
				
			||||||
 | 
					let _lcd_setcgramaddr        = (0x40)
 | 
				
			||||||
 | 
					let _lcd_setddramaddr        = (0x80)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Entry flags *)
 | 
				
			||||||
 | 
					let _lcd_entryleft           = (0x02)
 | 
				
			||||||
 | 
					let _lcd_entryshiftdecrement = (0x00)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Control flags *)
 | 
				
			||||||
 | 
					let _lcd_displayon           = (0x04)
 | 
				
			||||||
 | 
					let _lcd_cursoron            = (0x02)
 | 
				
			||||||
 | 
					let _lcd_cursoroff           = (0x00)
 | 
				
			||||||
 | 
					let _lcd_blinkon             = (0x01)
 | 
				
			||||||
 | 
					let _lcd_blinkoff            = (0x00)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Move flags *)
 | 
				
			||||||
 | 
					let _lcd_displaymove         = (0x08)
 | 
				
			||||||
 | 
					let _lcd_moveright           = (0x04)
 | 
				
			||||||
 | 
					let _lcd_moveleft            = (0x00)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Function set flags *)
 | 
				
			||||||
 | 
					let _lcd_4bitmode            = (0x00)
 | 
				
			||||||
 | 
					let _lcd_2line               = (0x08)
 | 
				
			||||||
 | 
					let _lcd_1line               = (0x00)
 | 
				
			||||||
 | 
					let _lcd_5x8dots             = (0x00)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Offset for up to 4 rows. *)
 | 
				
			||||||
 | 
					let _lcd_row_offsets = [|0x00; 0x40; 0x14; 0x54|]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let pulse_enable lcd =
 | 
				
			||||||
 | 
					  digital_write lcd.en LOW;
 | 
				
			||||||
 | 
					  (* 1 microsec pause *)
 | 
				
			||||||
 | 
					  Unix.sleepf(0.0000001);
 | 
				
			||||||
 | 
					  digital_write lcd.en HIGH;
 | 
				
			||||||
 | 
					  Unix.sleepf(0.0000001);
 | 
				
			||||||
 | 
					  digital_write lcd.en LOW;
 | 
				
			||||||
 | 
					  Unix.sleepf(0.00001)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(** write 8 bits of data *)
 | 
				
			||||||
 | 
					let write8 lcd ?(char_mode=false) value =
 | 
				
			||||||
 | 
					  (* one ms delay to prevent writing too quickly *)
 | 
				
			||||||
 | 
					  Unix.sleepf(0.001);
 | 
				
			||||||
 | 
					  let char_mode_value = if char_mode then HIGH else LOW in
 | 
				
			||||||
 | 
					  digital_write lcd.rs char_mode_value;
 | 
				
			||||||
 | 
					  let val_of_int i = if i > 0 then HIGH else LOW in
 | 
				
			||||||
 | 
					  let ival = Char.code value in
 | 
				
			||||||
 | 
					  (* write the UPPER 4 bits (in reverse order) *)
 | 
				
			||||||
 | 
					  digital_write lcd.d4 (val_of_int ((ival lsr 4) land 1));
 | 
				
			||||||
 | 
					  digital_write lcd.d5 (val_of_int ((ival lsr 5) land 1));
 | 
				
			||||||
 | 
					  digital_write lcd.d6 (val_of_int ((ival lsr 6) land 1));
 | 
				
			||||||
 | 
					  digital_write lcd.d7 (val_of_int ((ival lsr 7) land 1));
 | 
				
			||||||
 | 
					  pulse_enable lcd;
 | 
				
			||||||
 | 
					  (* write the LOWER 4 bits *)
 | 
				
			||||||
 | 
					  digital_write lcd.d4 (val_of_int (ival land 1));
 | 
				
			||||||
 | 
					  digital_write lcd.d5 (val_of_int ((ival lsr 1) land 1));
 | 
				
			||||||
 | 
					  digital_write lcd.d6 (val_of_int ((ival lsr 2) land 1));
 | 
				
			||||||
 | 
					  digital_write lcd.d7 (val_of_int ((ival lsr 3) land 1));
 | 
				
			||||||
 | 
					  pulse_enable lcd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(** same as [write8] but write an int (must be within the range) *)
 | 
				
			||||||
 | 
					let write8_unsafe lcd ?(char_mode=false) ival =
 | 
				
			||||||
 | 
					  write8 lcd ~char_mode (Char.unsafe_chr ival)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let setup lcd =
 | 
				
			||||||
 | 
					  Gpio3.setup ();
 | 
				
			||||||
 | 
					  pin_mode lcd.rs OUT;
 | 
				
			||||||
 | 
					  pin_mode lcd.en OUT;
 | 
				
			||||||
 | 
					  pin_mode lcd.d4 OUT;
 | 
				
			||||||
 | 
					  pin_mode lcd.d5 OUT;
 | 
				
			||||||
 | 
					  pin_mode lcd.d6 OUT;
 | 
				
			||||||
 | 
					  pin_mode lcd.d7 OUT;
 | 
				
			||||||
 | 
					  (* MAGIC *)
 | 
				
			||||||
 | 
					  write8_unsafe lcd 0x33;
 | 
				
			||||||
 | 
					  write8_unsafe lcd 0x32;
 | 
				
			||||||
 | 
					  (* set up some stuff *)
 | 
				
			||||||
 | 
					  let displayctrl = _lcd_displayon lor _lcd_cursoroff lor _lcd_blinkoff in
 | 
				
			||||||
 | 
					  let displayfn = _lcd_4bitmode lor _lcd_1line lor _lcd_2line lor _lcd_5x8dots in
 | 
				
			||||||
 | 
					  let displaymode = _lcd_entryleft lor _lcd_entryshiftdecrement in
 | 
				
			||||||
 | 
					  write8_unsafe lcd (displayctrl lor _lcd_displaycontrol);
 | 
				
			||||||
 | 
					  write8_unsafe lcd (displayfn lor _lcd_functionset);
 | 
				
			||||||
 | 
					  write8_unsafe lcd (displaymode lor _lcd_entrymodeset);
 | 
				
			||||||
 | 
					  Unix.sleepf(0.003)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let clear lcd =
 | 
				
			||||||
 | 
					  write8_unsafe lcd _lcd_cleardisplay;
 | 
				
			||||||
 | 
					  Unix.sleepf(0.003)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let shift_left lcd =
 | 
				
			||||||
 | 
					  write8_unsafe lcd (_lcd_cursorshift lor _lcd_displaymove lor _lcd_moveleft)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let shift_right lcd =
 | 
				
			||||||
 | 
					  write8_unsafe lcd (_lcd_cursorshift lor _lcd_displaymove lor _lcd_moveright)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let set_position lcd x y =
 | 
				
			||||||
 | 
					  let c = x mod lcd.columns in
 | 
				
			||||||
 | 
					  let r = y mod lcd.rows in
 | 
				
			||||||
 | 
					  if (c < 0 || r < 0) then failwith "Lcd.set_position: Negative row or column";
 | 
				
			||||||
 | 
					  write8_unsafe lcd (_lcd_setddramaddr lor (c + _lcd_row_offsets.(r)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let write_bytes lcd bts =
 | 
				
			||||||
 | 
					  Bytes.iter (fun c -> write8 lcd c ~char_mode:true) bts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let _ =
 | 
				
			||||||
 | 
					  setup lcd;
 | 
				
			||||||
 | 
					  clear lcd;
 | 
				
			||||||
 | 
					  set_position lcd 0 0;
 | 
				
			||||||
 | 
					  write_bytes lcd (Bytes.of_string "Hello, world.")
 | 
				
			||||||
		Reference in New Issue
	
	Block a user