Skip to content

Instantly share code, notes, and snippets.

@dahnielson
Last active July 2, 2018 09:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dahnielson/2c74919bc4a26aa217a4784e535f6f97 to your computer and use it in GitHub Desktop.
Save dahnielson/2c74919bc4a26aa217a4784e535f6f97 to your computer and use it in GitHub Desktop.
I can't work out why this doesn't work properly...
#include "lcd.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define ENABLE 0x03
#define E_PULSE 500
#define E_DELAY 500
#define LCD_BACKLIGHT 0x08
int lcd_open(const char* filename, const uint8_t address) {
int file;
if ((file = open(filename, O_RDWR)) < 0) {
perror("lcd_open: Failed to open the i2c bus");
}
if (ioctl(file, I2C_SLAVE, address) < 0) {
perror("lcd_open: Failed to acquire bus access");
}
return file;
}
void lcd_init(int device) {
lcd_write_byte(device, 0x33, LCD_CMD); // 110011 Initialise
lcd_write_byte(device, 0x32, LCD_CMD); // 110010 Initialise
lcd_write_byte(device, 0x06, LCD_CMD); // 000110 Cursor move direction
lcd_write_byte(device, 0x0C, LCD_CMD); // 001100 Display On, Cursor Off, Blink Off
lcd_write_byte(device, 0x28, LCD_CMD); // 101000 Data length, number of lines, font size
lcd_write_byte(device, 0x01, LCD_CMD); // 000001 Clear display
usleep(E_DELAY);
}
void _lcd_send(int device, const uint8_t value) {
i2c_smbus_write_byte(device, value);
}
void _lcd_toggle_enable(int device, const uint8_t bits) {
usleep(E_DELAY);
_lcd_send(device, (bits | ENABLE));
usleep(E_PULSE);
_lcd_send(device, (bits & ~ENABLE));
usleep(E_DELAY);
}
void lcd_write_byte(int device, const uint8_t byte, const uint8_t mode) {
const uint8_t bits_high = mode | (byte & 0xF0) | LCD_BACKLIGHT;
_lcd_send(device, bits_high);
_lcd_toggle_enable(device, bits_high);
const uint8_t bits_low = mode | ((byte << 4) & 0xF0) | LCD_BACKLIGHT;
_lcd_send(device, bits_low);
_lcd_toggle_enable(device, bits_low);
}
#ifndef _LCD_H
#define _LCD_H
#include <stdint.h>
#define LCD_LINE_1 0x80
#define LCD_LINE_2 0xC0
#define LCD_LINE_3 0x94
#define LCD_LINE_4 0xD4
#define LCD_CMD 0
#define LCD_CHR 1
int lcd_open(const char* filename, const uint8_t address);
void lcd_init(int device);
void lcd_write_byte(int device, const uint8_t value, const uint8_t mode);
#endif /* _LCD_H */
#include "lcd.h"
#include <stdlib.h>
#include <unistd.h>
int main(void) {
int device = lcd_open("/dev/i2c-1", 0x27);
lcd_init(device);
lcd_write_byte(device, LCD_LINE_1, LCD_CMD);
lcd_write_byte(device, 'T', LCD_CHR);
lcd_write_byte(device, 'e', LCD_CHR);
lcd_write_byte(device, 's', LCD_CHR);
lcd_write_byte(device, 't', LCD_CHR);
sleep(3);
exit(0);
}
@dahnielson
Copy link
Author

So I tried to implement the RPiSpy test script in C. While the original Python script works (the 16x2 LCD display text) my C version does not and I can't figure out why.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment