I am trying to interface an LCD using I2C but can't quite understand how to do it.
I found this example
Here's the code:
i2c.h:
/* File: I2C_LCD.h */
#define _XTAL_FREQ 16000000
#define I2C_BaudRate 100000
#define SCL_D TRISC3
#define SDA_D TRISC4
#define LCD_BACKLIGHT 0x08
#define LCD_NOBACKLIGHT 0x00
#define LCD_FIRST_ROW 0x80
#define LCD_SECOND_ROW 0xC0
#define LCD_THIRD_ROW 0x94
#define LCD_FOURTH_ROW 0xD4
#define LCD_CLEAR 0x01
#define LCD_RETURN_HOME 0x02
#define LCD_ENTRY_MODE_SET 0x04
#define LCD_CURSOR_OFF 0x0C
#define LCD_UNDERLINE_ON 0x0E
#define LCD_BLINK_CURSOR_ON 0x0F
#define LCD_MOVE_CURSOR_LEFT 0x10
#define LCD_MOVE_CURSOR_RIGHT 0x14
#define LCD_TURN_ON 0x0C
#define LCD_TURN_OFF 0x08
#define LCD_SHIFT_LEFT 0x18
#define LCD_SHIFT_RIGHT 0x1E
#define LCD_TYPE 2 // 0 -> 5x7 | 1 -> 5x10 | 2 -> 2 lines
//-----------[ Functions' Prototypes ]--------------
//---[ I2C Routines ]---
void I2C__Init();
void I2C__Wait();
void I2C__Start();
void I2C__RepeatedStart();
void I2C__Stop();
void I2C_ACK();
void I2C_NACK();
unsigned char I2C__Write(unsigned char data);
unsigned char I2C_Read_Byte(void);
//---[ LCD Routines ]---
void LCD_Init(unsigned char I2C_Add);
void IO_Expander_Write(unsigned char Data);
void LCD_Write_4Bit(unsigned char Nibble);
void LCD_CMD(unsigned char CMD);
void LCD_Set_Cursor(unsigned char ROW, unsigned char COL);
void LCD_Write_Char(char);
void LCD_Write_String(char*);
void Backlight();
void noBacklight();
void LCD_SR();
void LCD_SL();
void LCD_Clear();
I2c.c
#include <xc.h>
#include "I2C.h"
unsigned char RS, i2c_add, BackLight_State = LCD_BACKLIGHT;
//---------------[ I2C Routines ]-------------------
//--------------------------------------------------
void I2C__Init()
{
SSPCON = 0x28;
SSPCON2 = 0x00;
SSPSTAT = 0x00;
SSPADD = ((_XTAL_FREQ/4)/I2C_BaudRate) - 1;
SCL_D = 1;
SDA_D = 1;
}
void I2C__Wait()
{
while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F));
}
void I2C__Start()
{
I2C__Wait();
SEN = 1;
}
void I2C__RepeatedStart()
{
I2C__Wait();
RSEN = 1;
}
void I2C__Stop()
{
I2C__Wait();
PEN = 1;
}
void I2C_ACK(void)
{
ACKDT = 0; // 0 -> ACK
I2C__Wait();
ACKEN = 1; // Send ACK
}
void I2C_NACK(void)
{
ACKDT = 1; // 1 -> NACK
I2C__Wait();
ACKEN = 1; // Send NACK
}
unsigned char I2C__Write(unsigned char data)
{
I2C__Wait();
SSPBUF = data;
while(!SSPIF); // Wait Until Completion
SSPIF = 0;
return ACKSTAT;
}
unsigned char I2C_Read_Byte(void)
{
//---[ Receive & Return A Byte ]---
I2C__Wait();
RCEN = 1; // Enable & Start Reception
while(!SSPIF); // Wait Until Completion
SSPIF = 0; // Clear The Interrupt Flag Bit
I2C__Wait();
return SSPBUF; // Return The Received Byte
}
//======================================================
//---------------[ LCD Routines ]----------------
//------------------------------------------------------
void LCD_Init(unsigned char I2C_Add)
{
i2c_add = I2C_Add;
IO_Expander_Write(0x00);
__delay_ms(30);
LCD_CMD(0x03);
__delay_ms(5);
LCD_CMD(0x03);
__delay_ms(5);
LCD_CMD(0x03);
__delay_ms(5);
LCD_CMD(LCD_RETURN_HOME);
__delay_ms(5);
LCD_CMD(0x20 | (LCD_TYPE << 2));
__delay_ms(50);
LCD_CMD(LCD_TURN_ON);
__delay_ms(50);
LCD_CMD(LCD_CLEAR);
__delay_ms(50);
LCD_CMD(LCD_ENTRY_MODE_SET | LCD_RETURN_HOME);
__delay_ms(50);
}
void IO_Expander_Write(unsigned char Data)
{
I2C__Start();
I2C__Write(i2c_add);
I2C__Write(Data | BackLight_State);
I2C__Stop();
}
void LCD_Write_4Bit(unsigned char Nibble)
{
// Get The RS Value To LSB OF Data
Nibble |= RS;
IO_Expander_Write(Nibble | 0x04);
IO_Expander_Write(Nibble & 0xFB);
__delay_us(50);
}
void LCD_CMD(unsigned char CMD)
{
RS = 0; // Command Register Select
LCD_Write_4Bit(CMD & 0xF0);
LCD_Write_4Bit((CMD << 4) & 0xF0);
}
void LCD_Write_Char(char Data)
{
RS = 1; // Data Register Select
LCD_Write_4Bit(Data & 0xF0);
LCD_Write_4Bit((Data << 4) & 0xF0);
}
void LCD_Write_String(char* Str)
{
for(int i=0; Str[i]!='\0'; i++)
LCD_Write_Char(Str[i]);
}
void LCD_Set_Cursor(unsigned char ROW, unsigned char COL)
{
switch(ROW)
{
case 2:
LCD_CMD(0xC0 + COL-1);
break;
case 3:
LCD_CMD(0x94 + COL-1);
break;
case 4:
LCD_CMD(0xD4 + COL-1);
break;
// Case 1
default:
LCD_CMD(0x80 + COL-1);
}
}
void Backlight()
{
BackLight_State = LCD_BACKLIGHT;
IO_Expander_Write(0);
}
void noBacklight()
{
BackLight_State = LCD_NOBACKLIGHT;
IO_Expander_Write(0);
}
void LCD_SL()
{
LCD_CMD(0x18);
__delay_us(40);
}
void LCD_SR()
{
LCD_CMD(0x1C);
__delay_us(40);
}
void LCD_Clear()
{
LCD_CMD(0x01);
__delay_us(40);
}
main.c:
#include "I2C.h"
void main(void) {
I2C__Init();
LCD_Init(0x4E); // Initialize LCD module with I2C address = 0x4E
LCD_Set_Cursor(1, 1);
LCD_Write_String(" Welcome To ");
LCD_Set_Cursor(2, 1);
LCD_Write_String(" MicroDigiSoft ");
delay_ms(2500);
while(1)
{
}
return;
}
But I get these Errors:
Screenshot of Error
Screenshot of Error
I am using MikroC and one thing to note is that I have included the system libraries Lcd and Lcd Constants.
How can I fix these errors, and are there any examples of interfacing LCD I2C with microcontrollers apart from this?
You must import the I2C system libray in the the MikroC Library Manager, at the right panel. See the attached image:
Using NewPing.h seems to be the main issue.
Code:
#include <LedControl.h>
#include "pitches.h"
#include "SR04.h"
#include "NewPing.h"
#define TRIGGER_PIN 13
#define ECHO_PIN 8
#define MAX_DISTANCE 200
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
long duration;
int distance;
int DIN = 12;
int CS = 11;
int CLK = 10;
LedControl lc=LedControl(DIN,CLK,CS,0);
const int buzzer = 9;
void setup(){
lc.shutdown(0,false); //The MAX72XX is in power-saving mode on startup
lc.setIntensity(0,15); // Set the brightness to maximum value
lc.clearDisplay(0); // and clear the display
pinMode(buzzer, OUTPUT); //buzzer shit
pinMode(TRIGGER_PIN, OUTPUT); // Sets the trigPin as an OUTPUT
pinMode(ECHO_PIN, INPUT); // Sets the echoPin as an INPUT
Serial.begin(9600); // // Serial Communication is starting with 9600 of baudrate speed
}
void loop(){
unsigned int uS = sonar.ping();
Serial.print(uS / US_ROUNDTRIP_CM);
byte a[8]= {0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x18,};
byte b[8]= {0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x00,};
byte c[8]= {0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x18,}; //done
byte d[8] = {0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x18,}; //done
byte e[8]= {0x18,0x5a,0x3c,0x18,0x18,0x24,0x5a,0x18,}; //done
byte f[8]= {0x99,0x5a,0x18,0x18,0x18,0x00,0x5a,0x99,}; //done
byte g[8]= {0x99,0x18,0x18,0x18,0x18,0x00,0x18,0x99,};
byte h[8]= {0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x18,};
if (uS <= 20){
printByte(a);
tone(buzzer, 1000);
delay(100);
printByte(b);
noTone(buzzer);
delay(100);
printByte(c);
tone(buzzer, 1000);
delay(100);
printByte(d);
noTone(buzzer);
delay(100);
printByte(e);
tone(buzzer, 1000);
delay (100);
printByte(f);
noTone(buzzer);
delay (100);
printByte(g);
tone(buzzer, 1000);
delay (100);
printByte(h);
noTone(buzzer);
delay(1000);
}
}
void printByte(byte character [])
{
int i = 0;
for(i=0;i<8;i++)
{
lc.setRow(0,i,character[i]);
}
}
The main thing that stands out in the error is the line
"(.text+0x0): multiple definition of `__vector_13'
C:\Users\name\AppData\Local\Temp\arduino_build_789753\libraries\NewPing\NewPing.cpp.o (symbol from plugin):(.text+0x0): first defined here".
However, I don't exactly know how to solve it.
I'm working on Galileo gen 2;
And I'm trying to use the following two web services:
POST /dashboard/read_write_ard.php?temp="+tempValue
POST /dashboard/appinsert.php?valeur="+tempValue
The first one inserts into table one...
and the second one will be used only if (tempValue < 24).
This is my code so far:
#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h>
#include "rgb_lcd.h"
rgb_lcd lcd;
const int pinLight = A1;
const int pinLed = 13;
const int thresholdvalue = 400;
const int idealLightValue = 400 ;
const int pinTemp = A0;
const int B = 3975;
int etat=0;
const int pinSound = A2;
byte mac[] = {
0x98, 0x4F, 0xEE, 0x05, 0x37, 0x33
};//adress mac du carte
EthernetClient client;
IPAddress server(192,168, 1,7);
void setup() {
Serial.begin(9600);
pinMode(pinLed, OUTPUT);
lcd.begin(16, 2);
delay(1000);
system("ifup eth0");
if (Ethernet.begin(mac) == 0) {
Serial.println("\nFailed to configure Ethernet using DHCP");
delay(500);
}
delay(1000);
Serial.println(Ethernet.localIP());
}
void loop() {
system("ifup eth0");
digitalWrite(pinLed, HIGH);
lcd.print("Starting to loop ");
delay(1000);
lcd.clear();
int TempSensorValue = analogRead(pinTemp);
int LightSensorValue = analogRead(pinLight);
int SoundSensorValue = analogRead(pinSound);
float resistance = (float)(1023-TempSensorValue)*10000/TempSensorValue;
int temperature = 1/(log(resistance/10000)/B+1/298.15)-273.15;
Serial.println( temperature);
Serial.println(SoundSensorValue);
Serial.println( LightSensorValue);
delay(1000);
String chEtat = "POST /dashboard/read_write_ard.php?temp=";
chEtat += temperature ;
chEtat += "&light=";
chEtat += LightSensorValue;
chEtat +="&sound=";
chEtat +=SoundSensorValue;
if (client.connect(server, 80) ) {
Serial.println("connected");
lcd.print("Connected ");
delay(500);
lcd.clear();
if (temperature <= 40 ){
String chEtat2 = "POST /dashboard/appinsert.php?valeur=";
chEtat2 += temperature ;
chEtat2 += "&type=temperature" ;
client.println(chEtat2);
client.println(chEtat);
}else{
client.println(chEtat);
client.println();
}
}
while (client.available()) {
char c = client.read();
Serial.print(c);
}
if(client.connected()) {
Serial.println();
Serial.println("disconnecting.");
lcd.print("Dissconnecting");
delay(1000);
lcd.clear();
client.stop();
for (;;);
}
}
I have a database containing 2 tables - one for alert values like temperature and the other for normal cases - so I want to put a code when my cart Galileo can add in table 1 : the normal one.
And in case of temperature, let's say more than 24, the value of that temperature will be added to the second table using the web service created for that.
I'd like to know how to get these data soon.
I'm trying to send the x and y values of a joystick between two arduino mega 2560 with an nrf24l01. So far I have a transmitter and reciever code but I get wrong values on the reciever.
Transmitter:
#include <SPI.h>
#include <RF24.h>
RF24 radio(7,8);
byte addresses[][6] = {"0x115331","0x222331"};
typedef struct{
int X;
int Y;
int K;
}
Values;
Values v;
void setup() {
pinMode(10, INPUT);
Serial.begin(115200);
radio.begin();
radio.setPALevel(RF24_PA_LOW);
radio.setChannel(108);
radio.setPayloadSize(32);
radio.openWritingPipe(addresses[1]);
radio.openReadingPipe(1,addresses[0]);
}
void loop() {
radio.stopListening();
v.X = analogRead(A0);
v.Y = analogRead(A1);
v.K = digitalRead(10);
Serial.print("X = ");
Serial.println(v.X);
Serial.print("Y = ");
Serial.println(v.Y);
Serial.print("Button status: ");
if (v.K == HIGH)
{
Serial.println("pressed");
}
else
{
Serial.println("not pressed");
}
radio.write(&v,sizeof(v));
delay(500);
}
Reciever:
#include <SPI.h>
#include <RF24.h>
RF24 radio(7,8);
byte addresses[][6] = {"0x115331","0x222331"};
typedef struct{
int X;
int Y;
int K;
}
Values;
Values v;
void setup() {
Serial.begin(115200);
radio.begin();
radio.setPALevel(RF24_PA_LOW);
radio.openWritingPipe(addresses[0]);
radio.openReadingPipe(1,addresses[1]);
radio.setChannel(108);
radio.setPayloadSize(32);
radio.startListening();
}
void loop() {
radio.startListening();
if ( radio.available() )
{
while(radio.available())
{
radio.read(&v, sizeof(v));
}
}
radio.stopListening();
Serial.println(v.X);
Serial.println(v.Y);
Serial.println(v.K);
delay(1000);
}
I'm using the pin configuration from this website: https://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
I have a problem: I can read the EEPROM from my ATtiny, but I can't write something in it.
Here is my code:
#include <EEPROM.h>
int addr = 0;
int val = 2;
void setup()
{
}
void loop()
{
EEPROM.write(addr, val);
addr = addr + 1;
if (addr == 512)
addr = 0;
}
EDIT
Now my write code is:
#include <EEPROM.h>
int addr = 0;
int val = 2;
void setup()
{
}
void loop()
{
EEPROM.write(addr, byte(val));
addr = addr + 1;
if (addr == 512)
while(1);
}
And my read code:
int address = 0;
byte value;
#include <SoftwareSerial.h>
void setup()
{
SSerial.begin(9600);
}
void loop()
{
value = EEPROM.read(address);
SSerial.print(address);
SSerial.print("\t");
SSerial.print(value, DEC);
SSerial.println();
address = address + 1;
if (address == 512){
address = 0;
delay(100000000);
}
}
I always get only teh value 255. On every adress.
Now I convert my int to byte. My int won't get over 255 in my case.
And by the way: can I create an int as byte? So I can use it like a normal int, but can write it directly?
You're writing a single byte, whereas an int is two bytes. You can use EEPROM.get() & EEPROM.put() for larger types (read/write only handle a single byte).
#include <EEPROM.h>
int addr = 0;
int val = 2;
void setup(){}
void loop(){
//Write value
EEPROM.put(addr, val);
//Read value
EEPROM.get(addr, val);
addr += sizeof(int); //Increment cursor by two otherwise writes will overlap.
if(addr == EEPROM.length())
addr = 0;
}
as Vladimir Tsykunov mentioned, this test code can be bad for your EEPROM as it will loop many times while running. It may be better to stop the loop after one iteration:
if(addr == EEPROM.length())
while(1); //Infinite loop
Try not write eeprom in a loop, i suppose, eeprom have limited number of write/read cycles. You should show values that you read and write in terminal.