diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3a17cbf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +sketch_* diff --git a/BH1750_serial/BH1750_serial.ino b/BH1750_serial/BH1750_serial.ino new file mode 100644 index 0000000..5a506f8 --- /dev/null +++ b/BH1750_serial/BH1750_serial.ino @@ -0,0 +1,68 @@ + +/* + This is a simple code to test BH1750FVI Light senosr + communicate using I2C Protocol + this library enable 2 slave device address + Main address 0x23 + secondary address 0x5C + connect this sensor as following : + VCC >>> 3.3V + SDA >>> A4 + SCL >>> A5 + addr >> A3 + Gnd >>>Gnd + + Written By : Mohannad Rawashdeh + + */ + + // First define the library : + +#include +#include + + +BH1750FVI LightSensor; + + +void setup() { // put your setup code here, to run once: + Serial.begin(9600); + LightSensor.begin(); + /* + Set the address for this sensor + you can use 2 different address + Device_Address_H "0x5C" + Device_Address_L "0x23" + you must connect Addr pin to A3 . + */ + LightSensor.SetAddress(Device_Address_L);//Address 0x5C + // To adjust the slave on other address , uncomment this line + // lightMeter.SetAddress(Device_Address_L); //Address 0x5C + //----------------------------------------------- + /* + set the Working Mode for this sensor + Select the following Mode: + Continuous_H_resolution_Mode + Continuous_H_resolution_Mode2 + Continuous_L_resolution_Mode + OneTime_H_resolution_Mode + OneTime_H_resolution_Mode2 + OneTime_L_resolution_Mode + + The data sheet recommanded To use Continuous_H_resolution_Mode + */ + + LightSensor.SetMode(Continuous_H_resolution_Mode); + + Serial.println("Running..."); +} + + +void loop() { + // put your main code here, to run repeatedly: + uint16_t lux = LightSensor.GetLightIntensity();// Get Lux value + Serial.print("LightX: "); + Serial.print(lux); + Serial.println(" lux"); + delay(250); +} diff --git a/I2C_SLAVE_PHOTORESISTOR/I2C_SLAVE_PHOTORESISTOR.ino b/I2C_SLAVE_PHOTORESISTOR/I2C_SLAVE_PHOTORESISTOR.ino new file mode 100644 index 0000000..e868cac --- /dev/null +++ b/I2C_SLAVE_PHOTORESISTOR/I2C_SLAVE_PHOTORESISTOR.ino @@ -0,0 +1,22 @@ + +#include + +int lightPin = 0; + +void setup() +{ + Wire.begin(7); // join i2c bus with address #7 + Wire.onRequest(requestEvent); // register event + Serial.begin(9600); //Begin serial communcation +} + +void loop() +{ + Serial.println(analogRead(lightPin)); + delay(1000); +} + +void requestEvent() +{ + Wire.write(analogRead(lightPin)); // respond with message of 6 bytes +} diff --git a/LM35BH1750LCDI2C/LM35BH1750LCDI2C.ino b/LM35BH1750LCDI2C/LM35BH1750LCDI2C.ino new file mode 100644 index 0000000..70b42f9 --- /dev/null +++ b/LM35BH1750LCDI2C/LM35BH1750LCDI2C.ino @@ -0,0 +1,88 @@ +// Written 2015 by Johannes Findeisen + +#include +#include +#include + +BH1750FVI LightSensor; +LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 20 chars and 4 line display + +// Define how many samples should be collected every $collectDelay miliseconds. +// After sample collection the temperature is beeing calculated and then +// send to the LCD. +int samples = 8; + +// Collect delay between each sample. +int collectDelay = 1000; + +// The pin where the status LED is connected to. +int ledPin = 13; + +// The analog input pin where the LM35 is connected to. +int tempPin = 0; + +// Just some variable initializations. +float tempC = 0; +float tempClast = 0; +float tempF = 0; + +uint16_t lux = 0; + +void setup() +{ + pinMode(ledPin, OUTPUT); + LightSensor.begin(); + LightSensor.SetAddress(Device_Address_L); // Address 0x23 + LightSensor.SetMode(Continuous_H_resolution_Mode); + lcd.init(); + lcd.backlight(); + // Get data for the first time. + // Read this to understand the temperature calculation: + // http://www.danielandrade.net/2008/07/05/temperature-sensor-arduino/ + tempC = (5.0 * analogRead(tempPin) * 100.0) / 1024.0; + tempClast = tempC; + // Celsius to Fahrenheit conversion + tempF = (tempC * 9) / 5 + 32; + // Get light sensor data + lux = LightSensor.GetLightIntensity(); + // Refresh the LCD output + lcd_refresh(); +} + +void loop() +{ + int i; + tempC = 0; + for (i = 0; i <= (samples - 1); i++) { + tempC = tempC + ((5.0 * analogRead(tempPin) * 100.0) / 1024.0); + digitalWrite(ledPin, HIGH); + delay((collectDelay / 2)); + digitalWrite(ledPin, LOW); + delay((collectDelay / 2)); + } + // Calculate temperature + tempC = tempC / (float)samples; + // Celsius to Fahrenheit conversion. + tempF = (tempC * 9) / 5 + 32; + // Get light sensor data + lux = LightSensor.GetLightIntensity(); + // Print results to the display. + lcd_refresh(); + // Remember current temperature for next run. + tempClast = tempC; +} + +// Prints results to the display +void lcd_refresh() { + lcd.clear(); + lcd.setCursor(0, 0); + lcd.print(lux); + lcd.print(" Lux"); + lcd.setCursor(0, 1); + lcd.print(tempC); + lcd.print((char)223); // ASCII code 223 = "°" + lcd.print("C/"); + lcd.print(tempF); + lcd.print((char)223); // ASCII code 223 = "°" + lcd.print("F"); +} diff --git a/LM35BH1750LCDI2C_ArduinoI2C/LM35BH1750LCDI2C_ArduinoI2C.ino b/LM35BH1750LCDI2C_ArduinoI2C/LM35BH1750LCDI2C_ArduinoI2C.ino new file mode 100644 index 0000000..fbf56b9 --- /dev/null +++ b/LM35BH1750LCDI2C_ArduinoI2C/LM35BH1750LCDI2C_ArduinoI2C.ino @@ -0,0 +1,105 @@ +// Written 2015 by Johannes Findeisen + +#include +#include +#include + +BH1750FVI LightSensor; +LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 20 chars and 4 line display + +// Define how many samples should be collected every $collectDelay miliseconds. +// After sample collection the temperature is beeing calculated and then +// send to the LCD. +int samples = 8; + +// Collect delay between each sample. +int collectDelay = 1000; + +// The pin where the status LED is connected to. +int ledPin = 13; + +// The analog input pin where the LM35 is connected to. +int tempPin = 0; + +// Just some variable initializations. +float tempC = 0; +float tempClast = 0; +float tempF = 0; + +uint16_t lux = 0; + +int photo = 0; + +void setup() +{ + pinMode(ledPin, OUTPUT); + + Wire.begin(); + + LightSensor.begin(); + LightSensor.SetAddress(Device_Address_L); // Address 0x23 + LightSensor.SetMode(Continuous_H_resolution_Mode); + lcd.init(); + lcd.backlight(); + // Get data for the first time. + // Read this to understand the temperature calculation: + // http://www.danielandrade.net/2008/07/05/temperature-sensor-arduino/ + tempC = (5.0 * analogRead(tempPin) * 100.0) / 1024.0; + tempClast = tempC; + // Celsius to Fahrenheit conversion + tempF = (tempC * 9) / 5 + 32; + // Get light sensor data + lux = LightSensor.GetLightIntensity(); + // Get data from other Arduino on 0x07 + read_wire(); + // Refresh the LCD output + lcd_refresh(); +} + +void loop() +{ + int i; + tempC = 0; + for (i = 0; i <= (samples - 1); i++) { + tempC = tempC + ((5.0 * analogRead(tempPin) * 100.0) / 1024.0); + digitalWrite(ledPin, HIGH); + delay((collectDelay / 2)); + digitalWrite(ledPin, LOW); + delay((collectDelay / 2)); + } + // Calculate temperature + tempC = tempC / (float)samples; + // Celsius to Fahrenheit conversion. + tempF = (tempC * 9) / 5 + 32; + // Get light sensor data + lux = LightSensor.GetLightIntensity(); + // Get data from I2C attached Arduino + read_wire(); + // Print results to the display. + lcd_refresh(); + // Remember current temperature for next run. + tempClast = tempC; +} + +// Prints results to the display +void lcd_refresh() { + lcd.clear(); + lcd.setCursor(0, 0); + lcd.print(lux); + lcd.print(" Lux / "); + lcd.print(photo); + lcd.print(" Pr"); + lcd.setCursor(0, 1); + lcd.print(tempC); + lcd.print((char)223); // ASCII code 223 = "°" + lcd.print("C/"); + lcd.print(tempF); + lcd.print((char)223); // ASCII code 223 = "°" + lcd.print("F"); +} + +void read_wire() { + Wire.requestFrom(7, 1); // request 1 bytes from slave device #7 + photo = Wire.read(); +} + diff --git a/libraries/BH1750FVI/BH1750FVI.cpp b/libraries/BH1750FVI/BH1750FVI.cpp new file mode 100644 index 0000000..dcddda1 --- /dev/null +++ b/libraries/BH1750FVI/BH1750FVI.cpp @@ -0,0 +1,80 @@ +#include "BH1750FVI.h" +#include "Arduino.h" + +BH1750FVI::BH1750FVI(){ + + } + + void BH1750FVI::begin(void){ + Wire.begin(); + I2CWriteTo(Power_On ); //Turn it On + pinMode(AddrPin,OUTPUT); + digitalWrite(AddrPin,HIGH); + + } + void BH1750FVI::Sleep(void){ + I2CWriteTo(Power_Down ); //Turn it off , Reset operator won't work in this mode + } + void BH1750FVI::Reset(void){ + I2CWriteTo(Power_On ); //Turn it on again + I2CWriteTo(reset ); //Reset + + } + void BH1750FVI::SetAddress(uint8_t add){ + switch (add){ + case Device_Address_L: + address_value=Device_Address_L; + digitalWrite(AddrPin,LOW); + state=false; + break; + case Device_Address_H: + address_value=Device_Address_H; + digitalWrite(AddrPin,HIGH); + state=true; + break; + } + + } + void BH1750FVI::SetMode(uint8_t MODE){ + switch(MODE){ + case Continuous_H_resolution_Mode: + break; + case Continuous_H_resolution_Mode2: + break; + case Continuous_L_resolution_Mode: + break; + case OneTime_H_resolution_Mode: + break; + case OneTime_H_resolution_Mode2: + break; + case OneTime_L_resolution_Mode: + break; + } + delay(10); + I2CWriteTo(MODE); + } + + uint16_t BH1750FVI::GetLightIntensity(void){ + uint16_t Intensity_value; + if(state ==true){ + Wire.beginTransmission(Device_Address_H); + Wire.requestFrom(Device_Address_H, 2); + } + if(state ==false){ + Wire.beginTransmission(Device_Address_L); + Wire.requestFrom(Device_Address_L, 2); + } + Intensity_value = Wire.read(); + Intensity_value <<= 8; + Intensity_value |= Wire.read(); + Wire.endTransmission(); + Intensity_value=Intensity_value/1.2; + return Intensity_value; + + } + + void BH1750FVI::I2CWriteTo(uint8_t DataToSend){ + Wire.beginTransmission(address_value); + Wire.write(DataToSend); + Wire.endTransmission(); + } diff --git a/libraries/BH1750FVI/BH1750FVI.h b/libraries/BH1750FVI/BH1750FVI.h new file mode 100644 index 0000000..eea3fa8 --- /dev/null +++ b/libraries/BH1750FVI/BH1750FVI.h @@ -0,0 +1,68 @@ + + +/* This library for Digital Light sensor BH1750FVI + + use I2C Communication protocal , SDA,SCL Are required + + to interface with this sensor + + pin configuration : + + VCC >>> 3.3V + SDA >>> A4 + SCL >>> A5 + ADDR >> A3 "Optional" + GND >>> gnd + + written By : Mohannad Rawashdeh + www.genotronex.com + */ + +#ifndef BH1750FVI_h +#define BH1750FVI_h + +#include "Arduino.h" + +#include "Wire.h" + +#define Device_Address_L 0x23 // Device address when address pin LOW +#define Device_Address_H 0x5C // Device address when address pin LOW +//all command here taken from Data sheet OPECODE Table page 5 +#define Power_Down 0x00 + +#define Power_On 0x01 + +#define reset 0x07 + +#define Continuous_H_resolution_Mode 0x10 + +#define Continuous_H_resolution_Mode2 0x11 + +#define Continuous_L_resolution_Mode 0x13 + +#define OneTime_H_resolution_Mode 0x20 + +#define OneTime_H_resolution_Mode2 0x21 + +#define OneTime_L_resolution_Mode 0x23//As well as address value + +#define AddrPin 17 // Address pin enable + class BH1750FVI { + public: + BH1750FVI(); + void begin(void); + void Sleep(void); + void SetMode(uint8_t MODE); + void Reset(void); + void SetAddress(uint8_t add); + uint16_t GetLightIntensity(void); + + private: + void I2CWriteTo(uint8_t DataToSend); + byte address_value; + boolean state; + }; + #endif + + + diff --git a/libraries/BH1750FVI/BH1750_LCD/BH1750_LCD.ino b/libraries/BH1750FVI/BH1750_LCD/BH1750_LCD.ino new file mode 100644 index 0000000..ca5fd9d --- /dev/null +++ b/libraries/BH1750FVI/BH1750_LCD/BH1750_LCD.ino @@ -0,0 +1,60 @@ + /* + This is a simple code to test BH1750FVI Light senosr + communicate using I2C Protocol + this library enable 2 slave device address + Main address 0x23 + secondary address 0x5C + connect this sensor as following : + VCC >>> 3.3V + SDA >>> A4 + SCL >>> A5 + addr >> A3 + Gnd >>>Gnd + + Written By : Mohannad Rawashdeh + + */ + + // First define the library : + #include // Sensor Library + #include // I2C Library + #include + + LiquidCrystal lcd(12, 11, 5, 4, 3, 2); + uint16_t Light_Intensity=0; + // Call the function + + BH1750FVI LightSensor; + + +void setup() { + // put your setup code here, to run once: + Serial.begin(9600); + lcd.begin(16, 2); + + // call begin Function so turn the sensor On . + LightSensor.begin(); + LightSensor.SetAddress(Device_Address_H); //Address 0x5C + LightSensor.SetMode(Continuous_H_resolution_Mode); + lcd.setCursor(0, 0); + lcd.print("BH1750 Sensor"); + lcd.setCursor(1, 1); + lcd.print("Please wait..."); + delay(3000); + lcd.clear(); + +} + + void loop() { + // put your main code here, to run repeatedly: + lcd.clear(); + lcd.setCursor(0, 0); + lcd.print(" Intensity = "); + lcd.setCursor(5, 1); + Light_Intensity = LightSensor.GetLightIntensity(); + lcd.print(Light_Intensity); + lcd.print(" Lux"); + delay(2000); + + +} diff --git a/libraries/BH1750FVI/BH1750_Led/BH1750_Led.ino b/libraries/BH1750FVI/BH1750_Led/BH1750_Led.ino new file mode 100644 index 0000000..49015e3 --- /dev/null +++ b/libraries/BH1750FVI/BH1750_Led/BH1750_Led.ino @@ -0,0 +1,74 @@ +/* + This is a simple code to test BH1750FVI Light senosr + communicate using I2C Protocol + this library enable 2 slave device address + Main address 0x23 + secondary address 0x5C + connect this sensor as following : + VCC >>> 3.3V + SDA >>> A4 + SCL >>> A5 + addr >> A3 + Gnd >>>Gnd + + Written By : Mohannad Rawashdeh + + */ + + // First define the library : + #include // Sensor Library + #include // I2C Library + + uint16_t Light_Intensity=0; + // Call the function + #define LedPin 9 // led connecting to pin D9 + BH1750FVI LightSensor; + + int SensorValue =0; +void setup() { + // put your setup code here, to run once: + Serial.begin(9600); + // call begin Function so turn the sensor On . + LightSensor.begin(); + /* + Set the address for this sensor + you can use 2 different address + Device_Address_H "0x5C" + Device_Address_L "0x23" + you must connect Addr pin to A3 . + */ + LightSensor.SetAddress(Device_Address_H); //Address 0x5C + // To adjust the slave on other address , uncomment this line + // lightMeter.SetAddress(Device_Address_L); //Address 0x5C + //----------------------------------------------- + /* + set the Working Mode for this sensor + Select the following Mode: + Continuous_H_resolution_Mode + Continuous_H_resolution_Mode2 + Continuous_L_resolution_Mode + OneTime_H_resolution_Mode + OneTime_H_resolution_Mode2 + OneTime_L_resolution_Mode + + The data sheet recommanded To use Continuous_H_resolution_Mode + */ + LightSensor.SetMode(Continuous_H_resolution_Mode); + pinMode(9,OUTPUT) // Connect LED With 100ohm resistor + // to pin D9 + + +} + +void loop() { + // put your main code here, to run repeatedly: + // call GetLightIntensity() Function , so the sensor read + //the Intensity Value and send it + Light_Intensity=LightSensor.GetLightIntensity(); + delay(50); + + SensorValue=map(Light_Intensity,0,2000,255,0); + SensorValue=constrain(SensorValue,255,0); + digitalWrite(LedPin,SensorValue); + // ready to another reading . +} diff --git a/libraries/BH1750FVI/BH1750_serial/BH1750_serial.ino b/libraries/BH1750FVI/BH1750_serial/BH1750_serial.ino new file mode 100644 index 0000000..d475315 --- /dev/null +++ b/libraries/BH1750FVI/BH1750_serial/BH1750_serial.ino @@ -0,0 +1,68 @@ + +/* + This is a simple code to test BH1750FVI Light senosr + communicate using I2C Protocol + this library enable 2 slave device address + Main address 0x23 + secondary address 0x5C + connect this sensor as following : + VCC >>> 3.3V + SDA >>> A4 + SCL >>> A5 + addr >> A3 + Gnd >>>Gnd + + Written By : Mohannad Rawashdeh + + */ + + // First define the library : + +#include +#include + + +BH1750FVI LightSensor; + + +void setup() { // put your setup code here, to run once: + Serial.begin(9600); + LightSensor.begin(); + /* + Set the address for this sensor + you can use 2 different address + Device_Address_H "0x5C" + Device_Address_L "0x23" + you must connect Addr pin to A3 . + */ + LightSensor.SetAddress(Device_Address_H);//Address 0x5C + // To adjust the slave on other address , uncomment this line + // lightMeter.SetAddress(Device_Address_L); //Address 0x5C + //----------------------------------------------- + /* + set the Working Mode for this sensor + Select the following Mode: + Continuous_H_resolution_Mode + Continuous_H_resolution_Mode2 + Continuous_L_resolution_Mode + OneTime_H_resolution_Mode + OneTime_H_resolution_Mode2 + OneTime_L_resolution_Mode + + The data sheet recommanded To use Continuous_H_resolution_Mode + */ + + LightSensor.SetMode(Continuous_H_resolution_Mode); + + Serial.println("Running..."); +} + + +void loop() { + // put your main code here, to run repeatedly: + uint16_t lux = LightSensor.GetLightIntensity();// Get Lux value + Serial.print("Light: "); + Serial.print(lux); + Serial.println(" lux"); + delay(1000); +} diff --git a/libraries/BH1750FVI/keywords.txt b/libraries/BH1750FVI/keywords.txt new file mode 100644 index 0000000..feeee11 --- /dev/null +++ b/libraries/BH1750FVI/keywords.txt @@ -0,0 +1,24 @@ +####################################### +# Syntax Coloring Map For BH1750FVI +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + + KEYWORD1 +BH1750FVI KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + + +KEYWORD2 +begin KEYWORD2 +Sleep KEYWORD2SetMode KEYWORD2Reset KEYWORD2GetLightIntensity KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/libraries/LiquidCrystal_I2C/.gitattributes b/libraries/LiquidCrystal_I2C/.gitattributes new file mode 100644 index 0000000..412eeda --- /dev/null +++ b/libraries/LiquidCrystal_I2C/.gitattributes @@ -0,0 +1,22 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp +*.sln merge=union +*.csproj merge=union +*.vbproj merge=union +*.fsproj merge=union +*.dbproj merge=union + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/libraries/LiquidCrystal_I2C/.gitignore b/libraries/LiquidCrystal_I2C/.gitignore new file mode 100644 index 0000000..5d615ce --- /dev/null +++ b/libraries/LiquidCrystal_I2C/.gitignore @@ -0,0 +1,71 @@ +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +# ========================= +# Operating System Files +# ========================= + +# OSX +# ========================= + +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear on external disk +.Spotlight-V100 +.Trashes + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# Windows +# ========================= + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp diff --git a/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp b/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp new file mode 100644 index 0000000..636ca98 --- /dev/null +++ b/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp @@ -0,0 +1,305 @@ +// LiquidCrystal_I2C V2.0 - Mario H. atmega@xs4all.nl +// Mods for Chinese I2C converter board - Murray R. Van Luyn. vanluynm@iinet.net.au + +#include "LiquidCrystal_I2C.h" +#include +#include "Wire.h" +#include "Arduino.h" + + +// When the display powers up, it is configured as follows: +// +// 1. Display clear +// 2. Function set: +// DL = 1; 8-bit interface data +// N = 0; 1-line display +// F = 0; 5x8 dot character font +// 3. Display on/off control: +// D = 0; Display off +// C = 0; Cursor off +// B = 0; Blinking off +// 4. Entry mode set: +// I/D = 1; Increment by 1 +// S = 0; No shift +// +// Note, however, that resetting the Arduino doesn't reset the LCD, so we +// can't assume that its in that state when a sketch starts (and the +// LiquidCrystal constructor is called). + +LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows) +{ + _Addr = lcd_Addr; + _cols = lcd_cols; + _rows = lcd_rows; + _backlightval = LCD_NOBACKLIGHT; +} + +void LiquidCrystal_I2C::init(){ + init_priv(); +} + +void LiquidCrystal_I2C::init_priv() +{ + Wire.begin(); + _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; + begin(_cols, _rows); +} + +void LiquidCrystal_I2C::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) { + if (lines > 1) { + _displayfunction |= LCD_2LINE; + } + _numlines = lines; + + // for some 1 line displays you can select a 10 pixel high font + if ((dotsize != 0) && (lines == 1)) { + _displayfunction |= LCD_5x10DOTS; + } + + // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! + // according to datasheet, we need at least 40ms after power rises above 2.7V + // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50 + delayMicroseconds(50000); + + // Now we pull both RS and R/W low to begin commands + expanderWrite(_backlightval); // reset expanderand turn backlight off (Bit 8 =1) + delay(1000); + + //put the LCD into 4 bit mode + // this is according to the hitachi HD44780 datasheet + // figure 24, pg 46 + + // we start in 8bit mode, try to set 4 bit mode + write4bits(0x30); + delayMicroseconds(4500); // wait min 4.1ms + + // second try + write4bits(0x30); + delayMicroseconds(4500); // wait min 4.1ms + + // third go! + write4bits(0x30); + delayMicroseconds(150); + + // finally, set to 4-bit interface + write4bits(0x20); + + + // set # lines, font size, etc. + command(LCD_FUNCTIONSET | _displayfunction); + + // turn the display on with no cursor or blinking default + _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; + display(); + + // clear it off + clear(); + + // Initialize to default text direction (for roman languages) + _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; + + // set the entry mode + command(LCD_ENTRYMODESET | _displaymode); + + home(); + +} + + + +/********** high level commands, for the user! */ +void LiquidCrystal_I2C::clear(){ + command(LCD_CLEARDISPLAY);// clear display, set cursor position to zero + delayMicroseconds(2000); // this command takes a long time! +} + +void LiquidCrystal_I2C::home(){ + command(LCD_RETURNHOME); // set cursor position to zero + delayMicroseconds(2000); // this command takes a long time! +} + +void LiquidCrystal_I2C::setCursor(uint8_t col, uint8_t row){ + int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; + if ( row > _numlines ) { + row = _numlines-1; // we count rows starting w/0 + } + command(LCD_SETDDRAMADDR | (col + row_offsets[row])); +} + +// Turn the display on/off (quickly) +void LiquidCrystal_I2C::noDisplay() { + _displaycontrol &= ~LCD_DISPLAYON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal_I2C::display() { + _displaycontrol |= LCD_DISPLAYON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// Turns the underline cursor on/off +void LiquidCrystal_I2C::noCursor() { + _displaycontrol &= ~LCD_CURSORON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal_I2C::cursor() { + _displaycontrol |= LCD_CURSORON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// Turn on and off the blinking cursor +void LiquidCrystal_I2C::noBlink() { + _displaycontrol &= ~LCD_BLINKON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal_I2C::blink() { + _displaycontrol |= LCD_BLINKON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// These commands scroll the display without changing the RAM +void LiquidCrystal_I2C::scrollDisplayLeft(void) { + command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); +} +void LiquidCrystal_I2C::scrollDisplayRight(void) { + command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); +} + +// This is for text that flows Left to Right +void LiquidCrystal_I2C::leftToRight(void) { + _displaymode |= LCD_ENTRYLEFT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This is for text that flows Right to Left +void LiquidCrystal_I2C::rightToLeft(void) { + _displaymode &= ~LCD_ENTRYLEFT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This will 'right justify' text from the cursor +void LiquidCrystal_I2C::autoscroll(void) { + _displaymode |= LCD_ENTRYSHIFTINCREMENT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This will 'left justify' text from the cursor +void LiquidCrystal_I2C::noAutoscroll(void) { + _displaymode &= ~LCD_ENTRYSHIFTINCREMENT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// Allows us to fill the first 8 CGRAM locations +// with custom characters +void LiquidCrystal_I2C::createChar(uint8_t location, uint8_t charmap[]) { + location &= 0x7; // we only have 8 locations 0-7 + command(LCD_SETCGRAMADDR | (location << 3)); + for (int i=0; i<8; i++) { + write(charmap[i]); + } +} + +// Turn the (optional) backlight off/on +void LiquidCrystal_I2C::noBacklight(void) { + _backlightval=LCD_NOBACKLIGHT; + expanderWrite(0); +} + +void LiquidCrystal_I2C::backlight(void) { + _backlightval=LCD_BACKLIGHT; + expanderWrite(0); +} + + + +/*********** mid level commands, for sending data/cmds */ + +inline void LiquidCrystal_I2C::command(uint8_t value) { + send(value, 0); +} + +inline size_t LiquidCrystal_I2C::write(uint8_t value) { + send(value, Rs); + return 0; +} + + + +/************ low level data pushing commands **********/ + +// write either command or data +void LiquidCrystal_I2C::send(uint8_t value, uint8_t mode) { + uint8_t highnib = value & 0xF0; + uint8_t lownib = value << 4; + write4bits((highnib)|mode); + write4bits((lownib)|mode); +} + +void LiquidCrystal_I2C::write4bits(uint8_t value) { + expanderWrite(value); + pulseEnable(value); +} + +void LiquidCrystal_I2C::expanderWrite(uint8_t _data){ + Wire.beginTransmission(_Addr); + Wire.write((int)(_data) | _backlightval); + Wire.endTransmission(); +} + +void LiquidCrystal_I2C::pulseEnable(uint8_t _data){ + expanderWrite(_data | En); // En high + delayMicroseconds(1); // enable pulse must be >450ns + + expanderWrite(_data & ~En); // En low + delayMicroseconds(50); // commands need > 37us to settle +} + + +// Alias functions + +void LiquidCrystal_I2C::cursor_on(){ + cursor(); +} + +void LiquidCrystal_I2C::cursor_off(){ + noCursor(); +} + +void LiquidCrystal_I2C::blink_on(){ + blink(); +} + +void LiquidCrystal_I2C::blink_off(){ + noBlink(); +} + +void LiquidCrystal_I2C::load_custom_character(uint8_t char_num, uint8_t *rows){ + createChar(char_num, rows); +} + +void LiquidCrystal_I2C::setBacklight(uint8_t new_val){ + if(new_val){ + backlight(); // turn backlight on + }else{ + noBacklight(); // turn backlight off + } +} + +void LiquidCrystal_I2C::printstr(const char c[]){ + //This function is not identical to the function used for "real" I2C displays + //it's here so the user sketch doesn't have to be changed + print(c); +} + + +// unsupported API functions +void LiquidCrystal_I2C::off(){} +void LiquidCrystal_I2C::on(){} +void LiquidCrystal_I2C::setDelay (int cmdDelay,int charDelay) {} +uint8_t LiquidCrystal_I2C::status(){return 0;} +uint8_t LiquidCrystal_I2C::keypad (){return 0;} +uint8_t LiquidCrystal_I2C::init_bargraph(uint8_t graphtype){return 0;} +void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end){} +void LiquidCrystal_I2C::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_row_end){} +void LiquidCrystal_I2C::setContrast(uint8_t new_val){} + + diff --git a/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.h b/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.h new file mode 100644 index 0000000..2851098 --- /dev/null +++ b/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C.h @@ -0,0 +1,125 @@ +// LiquidCrystal_I2C V2.0 - Mario H. atmega@xs4all.nl +// Mods for Chinese I2C converter board - Murray R. Van Luyn. vanluynm@iinet.net.au + +#ifndef LiquidCrystal_I2C_h +#define LiquidCrystal_I2C_h + +#include +#include "Print.h" +#include + +// commands +#define LCD_CLEARDISPLAY 0x01 +#define LCD_RETURNHOME 0x02 +#define LCD_ENTRYMODESET 0x04 +#define LCD_DISPLAYCONTROL 0x08 +#define LCD_CURSORSHIFT 0x10 +#define LCD_FUNCTIONSET 0x20 +#define LCD_SETCGRAMADDR 0x40 +#define LCD_SETDDRAMADDR 0x80 + +// flags for display entry mode +#define LCD_ENTRYRIGHT 0x00 +#define LCD_ENTRYLEFT 0x02 +#define LCD_ENTRYSHIFTINCREMENT 0x01 +#define LCD_ENTRYSHIFTDECREMENT 0x00 + +// flags for display on/off control +#define LCD_DISPLAYON 0x04 +#define LCD_DISPLAYOFF 0x00 +#define LCD_CURSORON 0x02 +#define LCD_CURSOROFF 0x00 +#define LCD_BLINKON 0x01 +#define LCD_BLINKOFF 0x00 + +// flags for display/cursor shift +#define LCD_DISPLAYMOVE 0x08 +#define LCD_CURSORMOVE 0x00 +#define LCD_MOVERIGHT 0x04 +#define LCD_MOVELEFT 0x00 + +// flags for function set +#define LCD_8BITMODE 0x10 +#define LCD_4BITMODE 0x00 +#define LCD_2LINE 0x08 +#define LCD_1LINE 0x00 +#define LCD_5x10DOTS 0x04 +#define LCD_5x8DOTS 0x00 + +// flags for backlight control +#define LCD_BACKLIGHT B00001000 +#define LCD_NOBACKLIGHT B00000000 + +#define En B00000100 // Enable bit +#define Rw B00000010 // Read/Write bit +#define Rs B00000001 // Register select bit + +class LiquidCrystal_I2C : public Print { +public: + LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows); + void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS ); + void clear(); + void home(); + void noDisplay(); + void display(); + void noBlink(); + void blink(); + void noCursor(); + void cursor(); + void scrollDisplayLeft(); + void scrollDisplayRight(); + void printLeft(); + void printRight(); + void leftToRight(); + void rightToLeft(); + void shiftIncrement(); + void shiftDecrement(); + void noBacklight(); + void backlight(); + void autoscroll(); + void noAutoscroll(); + void createChar(uint8_t, uint8_t[]); + void setCursor(uint8_t, uint8_t); + virtual size_t write(uint8_t); + void command(uint8_t); + void init(); + + +////compatibility API function aliases +void blink_on(); // alias for blink() +void blink_off(); // alias for noBlink() +void cursor_on(); // alias for cursor() +void cursor_off(); // alias for noCursor() +void setBacklight(uint8_t new_val); // alias for backlight() and nobacklight() +void load_custom_character(uint8_t char_num, uint8_t *rows); // alias for createChar() +void printstr(const char[]); + +////Unsupported API functions (not implemented in this library) +uint8_t status(); +void setContrast(uint8_t new_val); +uint8_t keypad(); +void setDelay(int,int); +void on(); +void off(); +uint8_t init_bargraph(uint8_t graphtype); +void draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end); +void draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end); + + +private: + void init_priv(); + void send(uint8_t, uint8_t); + void write4bits(uint8_t); + void expanderWrite(uint8_t); + void pulseEnable(uint8_t); + uint8_t _Addr; + uint8_t _displayfunction; + uint8_t _displaycontrol; + uint8_t _displaymode; + uint8_t _numlines; + uint8_t _cols; + uint8_t _rows; + uint8_t _backlightval; +}; + +#endif diff --git a/libraries/LiquidCrystal_I2C/README.md b/libraries/LiquidCrystal_I2C/README.md new file mode 100644 index 0000000..603e88b --- /dev/null +++ b/libraries/LiquidCrystal_I2C/README.md @@ -0,0 +1,4 @@ +LiquidCrystal_I2C +================= + +A reimplementation of the standard Arduino LCD library, configured to work with parallel HD44780 compatible LCDs, and interfaced via a Chinese PCF8574 I2C serial extender. \ No newline at end of file diff --git a/libraries/LiquidCrystal_I2C/examples/CustomChars/CustomChars.ino b/libraries/LiquidCrystal_I2C/examples/CustomChars/CustomChars.ino new file mode 100644 index 0000000..e4f0783 --- /dev/null +++ b/libraries/LiquidCrystal_I2C/examples/CustomChars/CustomChars.ino @@ -0,0 +1,60 @@ +#include +#include + +uint8_t bell[8] = {0x4,0xe,0xe,0xe,0x1f,0x0,0x4}; +uint8_t note[8] = {0x2,0x3,0x2,0xe,0x1e,0xc,0x0}; +uint8_t clock[8] = {0x0,0xe,0x15,0x17,0x11,0xe,0x0}; +uint8_t heart[8] = {0x0,0xa,0x1f,0x1f,0xe,0x4,0x0}; +uint8_t duck[8] = {0x0,0xc,0x1d,0xf,0xf,0x6,0x0}; +uint8_t check[8] = {0x0,0x1,0x3,0x16,0x1c,0x8,0x0}; +uint8_t cross[8] = {0x0,0x1b,0xe,0x4,0xe,0x1b,0x0}; +uint8_t retarrow[8] = { 0x1,0x1,0x5,0x9,0x1f,0x8,0x4}; + +LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display + +void setup() +{ + lcd.init(); // initialize the lcd + lcd.backlight(); + + lcd.createChar(0, bell); + lcd.createChar(1, note); + lcd.createChar(2, clock); + lcd.createChar(3, heart); + lcd.createChar(4, duck); + lcd.createChar(5, check); + lcd.createChar(6, cross); + lcd.createChar(7, retarrow); + lcd.home(); + + lcd.print("Hello world..."); + lcd.setCursor(0, 1); + lcd.print(" i "); + lcd.write(3); + lcd.print(" arduinos!"); + delay(5000); + displayKeyCodes(); + +} + +// display all keycodes +void displayKeyCodes(void) { + uint8_t i = 0; + while (1) { + lcd.clear(); + lcd.print("Codes 0x"); lcd.print(i, HEX); + lcd.print("-0x"); lcd.print(i+16, HEX); + lcd.setCursor(0, 1); + for (int j=0; j<16; j++) { + lcd.write(i+j); + } + i+=16; + + delay(4000); + } +} + +void loop() +{ + +} diff --git a/libraries/LiquidCrystal_I2C/examples/HelloWorld/HelloWorld.ino b/libraries/LiquidCrystal_I2C/examples/HelloWorld/HelloWorld.ino new file mode 100644 index 0000000..3fe37fb --- /dev/null +++ b/libraries/LiquidCrystal_I2C/examples/HelloWorld/HelloWorld.ino @@ -0,0 +1,17 @@ +#include +#include + +LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 20 chars and 4 line display + +void setup() +{ + lcd.init(); // initialize the lcd + + // Print a message to the LCD. + lcd.backlight(); + lcd.print("Hello, world!"); +} + +void loop() +{ +} diff --git a/libraries/LiquidCrystal_I2C/examples/MultipleLcd/MultipleLcd.ino b/libraries/LiquidCrystal_I2C/examples/MultipleLcd/MultipleLcd.ino new file mode 100644 index 0000000..782e07f --- /dev/null +++ b/libraries/LiquidCrystal_I2C/examples/MultipleLcd/MultipleLcd.ino @@ -0,0 +1,24 @@ +#include +#include + +LiquidCrystal_I2C lcd1(0x26,16,2); // set the LCD address of the first lcd to 0x26 for a 16 chars and 2 line display +LiquidCrystal_I2C lcd2(0x27,16,2); // set the LCD address of the second lcd to 0x27 for a 16 chars and 2 line display + +void setup() +{ + lcd1.init(); // initialize the first lcd + lcd2.init(); // initialize the second lcd + + // Print a message on the first LCD. + lcd1.backlight(); + lcd1.print("Hello, #1 world!"); + + // Print a message on the second LCD. + lcd2.backlight(); + lcd2.print("Hello, #2 world!"); + +} + +void loop() +{ +} diff --git a/libraries/LiquidCrystal_I2C/examples/SerialDisplay/SerialDisplay.ino b/libraries/LiquidCrystal_I2C/examples/SerialDisplay/SerialDisplay.ino new file mode 100644 index 0000000..e776bf6 --- /dev/null +++ b/libraries/LiquidCrystal_I2C/examples/SerialDisplay/SerialDisplay.ino @@ -0,0 +1,31 @@ +/* + * Displays text sent over the serial port (e.g. from the Serial Monitor) on + * an attached LCD. + */ +#include +#include + +LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display + +void setup() +{ + lcd.init(); // initialize the lcd + lcd.backlight(); + Serial.begin(9600); +} + +void loop() +{ + // when characters arrive over the serial port... + if (Serial.available()) { + // wait a bit for the entire message to arrive + delay(100); + // clear the screen + lcd.clear(); + // read all the available characters + while (Serial.available() > 0) { + // display each character to the LCD + lcd.write(Serial.read()); + } + } +} diff --git a/libraries/LiquidCrystal_I2C/hardware/1602_I2C_LCD_Display.url b/libraries/LiquidCrystal_I2C/hardware/1602_I2C_LCD_Display.url new file mode 100644 index 0000000..90d4fed --- /dev/null +++ b/libraries/LiquidCrystal_I2C/hardware/1602_I2C_LCD_Display.url @@ -0,0 +1,5 @@ +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 +[InternetShortcut] +URL=http://www.banggood.com/IIC-Or-I2C-Or-TWI-SPI-LCD1602-Character-LCD-Module-For-Arduino-p-88316.html?p=5G0704100426201212C9 +IDList= diff --git a/libraries/LiquidCrystal_I2C/hardware/Blue_2004_I2C_LCD_Display.url b/libraries/LiquidCrystal_I2C/hardware/Blue_2004_I2C_LCD_Display.url new file mode 100644 index 0000000..d525bc7 --- /dev/null +++ b/libraries/LiquidCrystal_I2C/hardware/Blue_2004_I2C_LCD_Display.url @@ -0,0 +1,5 @@ +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 +[InternetShortcut] +URL=http://www.banggood.com/IIC-Or-I2C-2004-204-20-X-4-Character-LCD-Display-Module-Blue-p-908616.html?p=5G0704100426201212C9 +IDList= diff --git a/libraries/LiquidCrystal_I2C/hardware/I2C_Serial_LCD_Converter_Board_1602_2004.url b/libraries/LiquidCrystal_I2C/hardware/I2C_Serial_LCD_Converter_Board_1602_2004.url new file mode 100644 index 0000000..bb854c1 --- /dev/null +++ b/libraries/LiquidCrystal_I2C/hardware/I2C_Serial_LCD_Converter_Board_1602_2004.url @@ -0,0 +1,5 @@ +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 +[InternetShortcut] +URL=http://www.banggood.com/IIC-Or-I2C-Or-TWI-Or-SP-Serial-Interface-Module-Port-For-5V-Arduino-1602LCD-p-80365.html?p=5G0704100426201212C9 +IDList= diff --git a/libraries/LiquidCrystal_I2C/hardware/Yellow_Green_2004_I2C_LCD_Display.url b/libraries/LiquidCrystal_I2C/hardware/Yellow_Green_2004_I2C_LCD_Display.url new file mode 100644 index 0000000..1ac28fd --- /dev/null +++ b/libraries/LiquidCrystal_I2C/hardware/Yellow_Green_2004_I2C_LCD_Display.url @@ -0,0 +1,5 @@ +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 +[InternetShortcut] +URL=http://www.banggood.com/IIC-Or-I2C-2004-204-20-X-4-Character-LCD-Display-Module-Yellow-Green-p-908821.html?p=5G0704100426201212C9 +IDList= diff --git a/libraries/LiquidCrystal_I2C/info/2004_I2C_Serial_LCD_Display.jpg b/libraries/LiquidCrystal_I2C/info/2004_I2C_Serial_LCD_Display.jpg new file mode 100644 index 0000000..64c30b5 Binary files /dev/null and b/libraries/LiquidCrystal_I2C/info/2004_I2C_Serial_LCD_Display.jpg differ diff --git a/libraries/LiquidCrystal_I2C/info/2004_Pinout.jpg b/libraries/LiquidCrystal_I2C/info/2004_Pinout.jpg new file mode 100644 index 0000000..1075560 Binary files /dev/null and b/libraries/LiquidCrystal_I2C/info/2004_Pinout.jpg differ diff --git a/libraries/LiquidCrystal_I2C/info/Arduino I2C LCD.url b/libraries/LiquidCrystal_I2C/info/Arduino I2C LCD.url new file mode 100644 index 0000000..3ac5c21 --- /dev/null +++ b/libraries/LiquidCrystal_I2C/info/Arduino I2C LCD.url @@ -0,0 +1,7 @@ +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 +[InternetShortcut] +URL=http://playground.arduino.cc/Code/LCDi2c +IDList= +IconFile=http://playground.arduino.cc/favicon.png +IconIndex=1 diff --git a/libraries/LiquidCrystal_I2C/info/Arduino LCD API.url b/libraries/LiquidCrystal_I2C/info/Arduino LCD API.url new file mode 100644 index 0000000..74bc86a --- /dev/null +++ b/libraries/LiquidCrystal_I2C/info/Arduino LCD API.url @@ -0,0 +1,5 @@ +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 +[InternetShortcut] +URL=http://playground.arduino.cc/Code/LCDAPI +IDList= diff --git a/libraries/LiquidCrystal_I2C/info/Character_Set.jpg b/libraries/LiquidCrystal_I2C/info/Character_Set.jpg new file mode 100644 index 0000000..878d10a Binary files /dev/null and b/libraries/LiquidCrystal_I2C/info/Character_Set.jpg differ diff --git a/libraries/LiquidCrystal_I2C/info/Chinese_I2C_Serial_LCD_Converter_Board_1602_2004.jpg b/libraries/LiquidCrystal_I2C/info/Chinese_I2C_Serial_LCD_Converter_Board_1602_2004.jpg new file mode 100644 index 0000000..12b6940 Binary files /dev/null and b/libraries/LiquidCrystal_I2C/info/Chinese_I2C_Serial_LCD_Converter_Board_1602_2004.jpg differ diff --git a/libraries/LiquidCrystal_I2C/info/PCF8574P.pdf b/libraries/LiquidCrystal_I2C/info/PCF8574P.pdf new file mode 100644 index 0000000..e164e76 Binary files /dev/null and b/libraries/LiquidCrystal_I2C/info/PCF8574P.pdf differ diff --git a/libraries/LiquidCrystal_I2C/info/readme.txt b/libraries/LiquidCrystal_I2C/info/readme.txt new file mode 100644 index 0000000..e60f8b2 --- /dev/null +++ b/libraries/LiquidCrystal_I2C/info/readme.txt @@ -0,0 +1,47 @@ +// LiquidCrystal_I2C V2.0 - Mario H. atmega@xs4all.nl +// Mods for Chinese I2C converter board - Murray R. Van Luyn. vanluynm@iinet.net.au + +The LiquidCrystal_I2C library is a modified version of the standard LiquidCrystal library as found on +the Arduino website. +This library is intended to be used when a parallel HD44780 compatible LCD is controlled over I2C using +a Chinese PCF8574 extender. +4 of the 8 outputs are used for LCD data lines 4 to 7. +4 outputs are used for the Enable, register-select, Read/Write and backlight control lines. + +The Chinese PCF8574 extender is available in two versions, the PCF8574 and the PCF8574A. +The only difference between the two is the I2C base address. +The base address for the PCF8574 is 0x27 and the base address for the PCF8574A is 0x4E. +The examples included in this zip file assume the use of an PCF8574 set for address 0x27 +(A0, A1 and A3 un-linked, so pulled high). + +For PCF8574 the addressing is: + +Jp3 Jp2 Jp1 +A2 A1 A0 Dec Hex +L L L 32 0x20 +L L H 33 0x21 +L H L 34 0x22 +L H H 35 0x23 +H L L 36 0x24 +H L H 37 0x25 +H H L 38 0x26 +H H H 39 0x27 + +For PCF8574A the addressing is: + +Jp3 Jp2 Jp1 +A2 A1 A0 Dec Hex +L L L 56 0x38 +L L H 57 0x39 +L H L 64 0x40 +L H H 74 0x4A +H L L 75 0x4B +H L H 76 0x4C +H H L 77 0x4D +H H H 78 0x4E + +For compatibility reasons this library contains some aliases for functions that are known under different +names in other libraries. This should make it fairly easy to implement the library in existing sketches +without changing to much code. +Functions not supported by this library will return nothing at all and in case a return value is expected +the function will return 0. diff --git a/libraries/LiquidCrystal_I2C/keywords.txt b/libraries/LiquidCrystal_I2C/keywords.txt new file mode 100644 index 0000000..198480f --- /dev/null +++ b/libraries/LiquidCrystal_I2C/keywords.txt @@ -0,0 +1,47 @@ +########################################### +# Syntax Coloring Map For LiquidCrystal_I2C +# Version 2.0 +########################################### + +########################################### +# Datatypes (KEYWORD1) +########################################### + +LiquidCrystal_I2C KEYWORD1 + +########################################### +# Methods and Functions (KEYWORD2) +########################################### +init KEYWORD2 +begin KEYWORD2 +clear KEYWORD2 +home KEYWORD2 +noDisplay KEYWORD2 +display KEYWORD2 +noBlink KEYWORD2 +blink KEYWORD2 +noCursor KEYWORD2 +cursor KEYWORD2 +scrollDisplayLeft KEYWORD2 +scrollDisplayRight KEYWORD2 +leftToRight KEYWORD2 +rightToLeft KEYWORD2 +shiftIncrement KEYWORD2 +shiftDecrement KEYWORD2 +noBacklight KEYWORD2 +backlight KEYWORD2 +autoscroll KEYWORD2 +noAutoscroll KEYWORD2 +createChar KEYWORD2 +setCursor KEYWORD2 +print KEYWORD2 +blink_on KEYWORD2 +blink_off KEYWORD2 +cursor_on KEYWORD2 +cursor_off KEYWORD2 +setBacklight KEYWORD2 +load_custom_character KEYWORD2 +printstr KEYWORD2 +########################################### +# Constants (LITERAL1) +########################################### diff --git a/libraries/OneWire/OneWire.cpp b/libraries/OneWire/OneWire.cpp new file mode 100644 index 0000000..631813f --- /dev/null +++ b/libraries/OneWire/OneWire.cpp @@ -0,0 +1,557 @@ +/* +Copyright (c) 2007, Jim Studt (original old version - many contributors since) + +The latest version of this library may be found at: + http://www.pjrc.com/teensy/td_libs_OneWire.html + +OneWire has been maintained by Paul Stoffregen (paul@pjrc.com) since +January 2010. At the time, it was in need of many bug fixes, but had +been abandoned the original author (Jim Studt). None of the known +contributors were interested in maintaining OneWire. Paul typically +works on OneWire every 6 to 12 months. Patches usually wait that +long. If anyone is interested in more actively maintaining OneWire, +please contact Paul. + +Version 2.2: + Teensy 3.0 compatibility, Paul Stoffregen, paul@pjrc.com + Arduino Due compatibility, http://arduino.cc/forum/index.php?topic=141030 + Fix DS18B20 example negative temperature + Fix DS18B20 example's low res modes, Ken Butcher + Improve reset timing, Mark Tillotson + Add const qualifiers, Bertrik Sikken + Add initial value input to crc16, Bertrik Sikken + Add target_search() function, Scott Roberts + +Version 2.1: + Arduino 1.0 compatibility, Paul Stoffregen + Improve temperature example, Paul Stoffregen + DS250x_PROM example, Guillermo Lovato + PIC32 (chipKit) compatibility, Jason Dangel, dangel.jason AT gmail.com + Improvements from Glenn Trewitt: + - crc16() now works + - check_crc16() does all of calculation/checking work. + - Added read_bytes() and write_bytes(), to reduce tedious loops. + - Added ds2408 example. + Delete very old, out-of-date readme file (info is here) + +Version 2.0: Modifications by Paul Stoffregen, January 2010: +http://www.pjrc.com/teensy/td_libs_OneWire.html + Search fix from Robin James + http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27 + Use direct optimized I/O in all cases + Disable interrupts during timing critical sections + (this solves many random communication errors) + Disable interrupts during read-modify-write I/O + Reduce RAM consumption by eliminating unnecessary + variables and trimming many to 8 bits + Optimize both crc8 - table version moved to flash + +Modified to work with larger numbers of devices - avoids loop. +Tested in Arduino 11 alpha with 12 sensors. +26 Sept 2008 -- Robin James +http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27 + +Updated to work with arduino-0008 and to include skip() as of +2007/07/06. --RJL20 + +Modified to calculate the 8-bit CRC directly, avoiding the need for +the 256-byte lookup table to be loaded in RAM. Tested in arduino-0010 +-- Tom Pollard, Jan 23, 2008 + +Jim Studt's original library was modified by Josh Larios. + +Tom Pollard, pollard@alum.mit.edu, contributed around May 20, 2008 + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Much of the code was inspired by Derek Yerger's code, though I don't +think much of that remains. In any event that was.. + (copyleft) 2006 by Derek Yerger - Free to distribute freely. + +The CRC code was excerpted and inspired by the Dallas Semiconductor +sample code bearing this copyright. +//--------------------------------------------------------------------------- +// Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES +// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +// Except as contained in this notice, the name of Dallas Semiconductor +// shall not be used except as stated in the Dallas Semiconductor +// Branding Policy. +//-------------------------------------------------------------------------- +*/ + +#include "OneWire.h" + + +OneWire::OneWire(uint8_t pin) +{ + pinMode(pin, INPUT); + bitmask = PIN_TO_BITMASK(pin); + baseReg = PIN_TO_BASEREG(pin); +#if ONEWIRE_SEARCH + reset_search(); +#endif +} + + +// Perform the onewire reset function. We will wait up to 250uS for +// the bus to come high, if it doesn't then it is broken or shorted +// and we return a 0; +// +// Returns 1 if a device asserted a presence pulse, 0 otherwise. +// +uint8_t OneWire::reset(void) +{ + IO_REG_TYPE mask = bitmask; + volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg; + uint8_t r; + uint8_t retries = 125; + + noInterrupts(); + DIRECT_MODE_INPUT(reg, mask); + interrupts(); + // wait until the wire is high... just in case + do { + if (--retries == 0) return 0; + delayMicroseconds(2); + } while ( !DIRECT_READ(reg, mask)); + + noInterrupts(); + DIRECT_WRITE_LOW(reg, mask); + DIRECT_MODE_OUTPUT(reg, mask); // drive output low + interrupts(); + delayMicroseconds(480); + noInterrupts(); + DIRECT_MODE_INPUT(reg, mask); // allow it to float + delayMicroseconds(70); + r = !DIRECT_READ(reg, mask); + interrupts(); + delayMicroseconds(410); + return r; +} + +// +// Write a bit. Port and bit is used to cut lookup time and provide +// more certain timing. +// +void OneWire::write_bit(uint8_t v) +{ + IO_REG_TYPE mask=bitmask; + volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg; + + if (v & 1) { + noInterrupts(); + DIRECT_WRITE_LOW(reg, mask); + DIRECT_MODE_OUTPUT(reg, mask); // drive output low + delayMicroseconds(10); + DIRECT_WRITE_HIGH(reg, mask); // drive output high + interrupts(); + delayMicroseconds(55); + } else { + noInterrupts(); + DIRECT_WRITE_LOW(reg, mask); + DIRECT_MODE_OUTPUT(reg, mask); // drive output low + delayMicroseconds(65); + DIRECT_WRITE_HIGH(reg, mask); // drive output high + interrupts(); + delayMicroseconds(5); + } +} + +// +// Read a bit. Port and bit is used to cut lookup time and provide +// more certain timing. +// +uint8_t OneWire::read_bit(void) +{ + IO_REG_TYPE mask=bitmask; + volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg; + uint8_t r; + + noInterrupts(); + DIRECT_MODE_OUTPUT(reg, mask); + DIRECT_WRITE_LOW(reg, mask); + delayMicroseconds(3); + DIRECT_MODE_INPUT(reg, mask); // let pin float, pull up will raise + delayMicroseconds(10); + r = DIRECT_READ(reg, mask); + interrupts(); + delayMicroseconds(53); + return r; +} + +// +// Write a byte. The writing code uses the active drivers to raise the +// pin high, if you need power after the write (e.g. DS18S20 in +// parasite power mode) then set 'power' to 1, otherwise the pin will +// go tri-state at the end of the write to avoid heating in a short or +// other mishap. +// +void OneWire::write(uint8_t v, uint8_t power /* = 0 */) { + uint8_t bitMask; + + for (bitMask = 0x01; bitMask; bitMask <<= 1) { + OneWire::write_bit( (bitMask & v)?1:0); + } + if ( !power) { + noInterrupts(); + DIRECT_MODE_INPUT(baseReg, bitmask); + DIRECT_WRITE_LOW(baseReg, bitmask); + interrupts(); + } +} + +void OneWire::write_bytes(const uint8_t *buf, uint16_t count, bool power /* = 0 */) { + for (uint16_t i = 0 ; i < count ; i++) + write(buf[i]); + if (!power) { + noInterrupts(); + DIRECT_MODE_INPUT(baseReg, bitmask); + DIRECT_WRITE_LOW(baseReg, bitmask); + interrupts(); + } +} + +// +// Read a byte +// +uint8_t OneWire::read() { + uint8_t bitMask; + uint8_t r = 0; + + for (bitMask = 0x01; bitMask; bitMask <<= 1) { + if ( OneWire::read_bit()) r |= bitMask; + } + return r; +} + +void OneWire::read_bytes(uint8_t *buf, uint16_t count) { + for (uint16_t i = 0 ; i < count ; i++) + buf[i] = read(); +} + +// +// Do a ROM select +// +void OneWire::select(const uint8_t rom[8]) +{ + uint8_t i; + + write(0x55); // Choose ROM + + for (i = 0; i < 8; i++) write(rom[i]); +} + +// +// Do a ROM skip +// +void OneWire::skip() +{ + write(0xCC); // Skip ROM +} + +void OneWire::depower() +{ + noInterrupts(); + DIRECT_MODE_INPUT(baseReg, bitmask); + interrupts(); +} + +#if ONEWIRE_SEARCH + +// +// You need to use this function to start a search again from the beginning. +// You do not need to do it for the first search, though you could. +// +void OneWire::reset_search() +{ + // reset the search state + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + for(int i = 7; ; i--) { + ROM_NO[i] = 0; + if ( i == 0) break; + } +} + +// Setup the search to find the device type 'family_code' on the next call +// to search(*newAddr) if it is present. +// +void OneWire::target_search(uint8_t family_code) +{ + // set the search state to find SearchFamily type devices + ROM_NO[0] = family_code; + for (uint8_t i = 1; i < 8; i++) + ROM_NO[i] = 0; + LastDiscrepancy = 64; + LastFamilyDiscrepancy = 0; + LastDeviceFlag = FALSE; +} + +// +// Perform a search. If this function returns a '1' then it has +// enumerated the next device and you may retrieve the ROM from the +// OneWire::address variable. If there are no devices, no further +// devices, or something horrible happens in the middle of the +// enumeration then a 0 is returned. If a new device is found then +// its address is copied to newAddr. Use OneWire::reset_search() to +// start over. +// +// --- Replaced by the one from the Dallas Semiconductor web site --- +//-------------------------------------------------------------------------- +// Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing +// search state. +// Return TRUE : device found, ROM number in ROM_NO buffer +// FALSE : device not found, end of search +// +uint8_t OneWire::search(uint8_t *newAddr) +{ + uint8_t id_bit_number; + uint8_t last_zero, rom_byte_number, search_result; + uint8_t id_bit, cmp_id_bit; + + unsigned char rom_byte_mask, search_direction; + + // initialize for search + id_bit_number = 1; + last_zero = 0; + rom_byte_number = 0; + rom_byte_mask = 1; + search_result = 0; + + // if the last call was not the last one + if (!LastDeviceFlag) + { + // 1-Wire reset + if (!reset()) + { + // reset the search + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + return FALSE; + } + + // issue the search command + write(0xF0); + + // loop to do the search + do + { + // read a bit and its complement + id_bit = read_bit(); + cmp_id_bit = read_bit(); + + // check for no devices on 1-wire + if ((id_bit == 1) && (cmp_id_bit == 1)) + break; + else + { + // all devices coupled have 0 or 1 + if (id_bit != cmp_id_bit) + search_direction = id_bit; // bit write value for search + else + { + // if this discrepancy if before the Last Discrepancy + // on a previous next then pick the same as last time + if (id_bit_number < LastDiscrepancy) + search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0); + else + // if equal to last pick 1, if not then pick 0 + search_direction = (id_bit_number == LastDiscrepancy); + + // if 0 was picked then record its position in LastZero + if (search_direction == 0) + { + last_zero = id_bit_number; + + // check for Last discrepancy in family + if (last_zero < 9) + LastFamilyDiscrepancy = last_zero; + } + } + + // set or clear the bit in the ROM byte rom_byte_number + // with mask rom_byte_mask + if (search_direction == 1) + ROM_NO[rom_byte_number] |= rom_byte_mask; + else + ROM_NO[rom_byte_number] &= ~rom_byte_mask; + + // serial number search direction write bit + write_bit(search_direction); + + // increment the byte counter id_bit_number + // and shift the mask rom_byte_mask + id_bit_number++; + rom_byte_mask <<= 1; + + // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask + if (rom_byte_mask == 0) + { + rom_byte_number++; + rom_byte_mask = 1; + } + } + } + while(rom_byte_number < 8); // loop until through all ROM bytes 0-7 + + // if the search was successful then + if (!(id_bit_number < 65)) + { + // search successful so set LastDiscrepancy,LastDeviceFlag,search_result + LastDiscrepancy = last_zero; + + // check for last device + if (LastDiscrepancy == 0) + LastDeviceFlag = TRUE; + + search_result = TRUE; + } + } + + // if no device found then reset counters so next 'search' will be like a first + if (!search_result || !ROM_NO[0]) + { + LastDiscrepancy = 0; + LastDeviceFlag = FALSE; + LastFamilyDiscrepancy = 0; + search_result = FALSE; + } + for (int i = 0; i < 8; i++) newAddr[i] = ROM_NO[i]; + return search_result; + } + +#endif + +#if ONEWIRE_CRC +// The 1-Wire CRC scheme is described in Maxim Application Note 27: +// "Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products" +// + +#if ONEWIRE_CRC8_TABLE +// This table comes from Dallas sample code where it is freely reusable, +// though Copyright (C) 2000 Dallas Semiconductor Corporation +static const uint8_t PROGMEM dscrc_table[] = { + 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, + 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, + 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, + 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, + 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, + 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, + 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, + 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, + 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, + 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, + 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, + 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, + 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, + 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, + 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, + 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53}; + +// +// Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM +// and the registers. (note: this might better be done without to +// table, it would probably be smaller and certainly fast enough +// compared to all those delayMicrosecond() calls. But I got +// confused, so I use this table from the examples.) +// +uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len) +{ + uint8_t crc = 0; + + while (len--) { + crc = pgm_read_byte(dscrc_table + (crc ^ *addr++)); + } + return crc; +} +#else +// +// Compute a Dallas Semiconductor 8 bit CRC directly. +// this is much slower, but much smaller, than the lookup table. +// +uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len) +{ + uint8_t crc = 0; + + while (len--) { + uint8_t inbyte = *addr++; + for (uint8_t i = 8; i; i--) { + uint8_t mix = (crc ^ inbyte) & 0x01; + crc >>= 1; + if (mix) crc ^= 0x8C; + inbyte >>= 1; + } + } + return crc; +} +#endif + +#if ONEWIRE_CRC16 +bool OneWire::check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc) +{ + crc = ~crc16(input, len, crc); + return (crc & 0xFF) == inverted_crc[0] && (crc >> 8) == inverted_crc[1]; +} + +uint16_t OneWire::crc16(const uint8_t* input, uint16_t len, uint16_t crc) +{ + static const uint8_t oddparity[16] = + { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; + + for (uint16_t i = 0 ; i < len ; i++) { + // Even though we're just copying a byte from the input, + // we'll be doing 16-bit computation with it. + uint16_t cdata = input[i]; + cdata = (cdata ^ crc) & 0xff; + crc >>= 8; + + if (oddparity[cdata & 0x0F] ^ oddparity[cdata >> 4]) + crc ^= 0xC001; + + cdata <<= 6; + crc ^= cdata; + cdata <<= 1; + crc ^= cdata; + } + return crc; +} +#endif + +#endif diff --git a/libraries/OneWire/OneWire.h b/libraries/OneWire/OneWire.h new file mode 100644 index 0000000..916c529 --- /dev/null +++ b/libraries/OneWire/OneWire.h @@ -0,0 +1,229 @@ +#ifndef OneWire_h +#define OneWire_h + +#include + +#if ARDUINO >= 100 +#include "Arduino.h" // for delayMicroseconds, digitalPinToBitMask, etc +#else +#include "WProgram.h" // for delayMicroseconds +#include "pins_arduino.h" // for digitalPinToBitMask, etc +#endif + +// You can exclude certain features from OneWire. In theory, this +// might save some space. In practice, the compiler automatically +// removes unused code (technically, the linker, using -fdata-sections +// and -ffunction-sections when compiling, and Wl,--gc-sections +// when linking), so most of these will not result in any code size +// reduction. Well, unless you try to use the missing features +// and redesign your program to not need them! ONEWIRE_CRC8_TABLE +// is the exception, because it selects a fast but large algorithm +// or a small but slow algorithm. + +// you can exclude onewire_search by defining that to 0 +#ifndef ONEWIRE_SEARCH +#define ONEWIRE_SEARCH 1 +#endif + +// You can exclude CRC checks altogether by defining this to 0 +#ifndef ONEWIRE_CRC +#define ONEWIRE_CRC 1 +#endif + +// Select the table-lookup method of computing the 8-bit CRC +// by setting this to 1. The lookup table enlarges code size by +// about 250 bytes. It does NOT consume RAM (but did in very +// old versions of OneWire). If you disable this, a slower +// but very compact algorithm is used. +#ifndef ONEWIRE_CRC8_TABLE +#define ONEWIRE_CRC8_TABLE 1 +#endif + +// You can allow 16-bit CRC checks by defining this to 1 +// (Note that ONEWIRE_CRC must also be 1.) +#ifndef ONEWIRE_CRC16 +#define ONEWIRE_CRC16 1 +#endif + +#define FALSE 0 +#define TRUE 1 + +// Platform specific I/O definitions + +#if defined(__AVR__) +#define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin))) +#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) +#define IO_REG_TYPE uint8_t +#define IO_REG_ASM asm("r30") +#define DIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0) +#define DIRECT_MODE_INPUT(base, mask) ((*((base)+1)) &= ~(mask)) +#define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+1)) |= (mask)) +#define DIRECT_WRITE_LOW(base, mask) ((*((base)+2)) &= ~(mask)) +#define DIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask)) + +#elif defined(__MK20DX128__) +#define PIN_TO_BASEREG(pin) (portOutputRegister(pin)) +#define PIN_TO_BITMASK(pin) (1) +#define IO_REG_TYPE uint8_t +#define IO_REG_ASM +#define DIRECT_READ(base, mask) (*((base)+512)) +#define DIRECT_MODE_INPUT(base, mask) (*((base)+640) = 0) +#define DIRECT_MODE_OUTPUT(base, mask) (*((base)+640) = 1) +#define DIRECT_WRITE_LOW(base, mask) (*((base)+256) = 1) +#define DIRECT_WRITE_HIGH(base, mask) (*((base)+128) = 1) + +#elif defined(__SAM3X8E__) +// Arduino 1.5.1 may have a bug in delayMicroseconds() on Arduino Due. +// http://arduino.cc/forum/index.php/topic,141030.msg1076268.html#msg1076268 +// If you have trouble with OneWire on Arduino Due, please check the +// status of delayMicroseconds() before reporting a bug in OneWire! +#define PIN_TO_BASEREG(pin) (&(digitalPinToPort(pin)->PIO_PER)) +#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) +#define IO_REG_TYPE uint32_t +#define IO_REG_ASM +#define DIRECT_READ(base, mask) (((*((base)+15)) & (mask)) ? 1 : 0) +#define DIRECT_MODE_INPUT(base, mask) ((*((base)+5)) = (mask)) +#define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+4)) = (mask)) +#define DIRECT_WRITE_LOW(base, mask) ((*((base)+13)) = (mask)) +#define DIRECT_WRITE_HIGH(base, mask) ((*((base)+12)) = (mask)) +#ifndef PROGMEM +#define PROGMEM +#endif +#ifndef pgm_read_byte +#define pgm_read_byte(addr) (*(const uint8_t *)(addr)) +#endif + +#elif defined(__PIC32MX__) +#define PIN_TO_BASEREG(pin) (portModeRegister(digitalPinToPort(pin))) +#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) +#define IO_REG_TYPE uint32_t +#define IO_REG_ASM +#define DIRECT_READ(base, mask) (((*(base+4)) & (mask)) ? 1 : 0) //PORTX + 0x10 +#define DIRECT_MODE_INPUT(base, mask) ((*(base+2)) = (mask)) //TRISXSET + 0x08 +#define DIRECT_MODE_OUTPUT(base, mask) ((*(base+1)) = (mask)) //TRISXCLR + 0x04 +#define DIRECT_WRITE_LOW(base, mask) ((*(base+8+1)) = (mask)) //LATXCLR + 0x24 +#define DIRECT_WRITE_HIGH(base, mask) ((*(base+8+2)) = (mask)) //LATXSET + 0x28 + +#else +#error "Please define I/O register types here" +#endif + + +class OneWire +{ + private: + IO_REG_TYPE bitmask; + volatile IO_REG_TYPE *baseReg; + +#if ONEWIRE_SEARCH + // global search state + unsigned char ROM_NO[8]; + uint8_t LastDiscrepancy; + uint8_t LastFamilyDiscrepancy; + uint8_t LastDeviceFlag; +#endif + + public: + OneWire( uint8_t pin); + + // Perform a 1-Wire reset cycle. Returns 1 if a device responds + // with a presence pulse. Returns 0 if there is no device or the + // bus is shorted or otherwise held low for more than 250uS + uint8_t reset(void); + + // Issue a 1-Wire rom select command, you do the reset first. + void select(const uint8_t rom[8]); + + // Issue a 1-Wire rom skip command, to address all on bus. + void skip(void); + + // Write a byte. If 'power' is one then the wire is held high at + // the end for parasitically powered devices. You are responsible + // for eventually depowering it by calling depower() or doing + // another read or write. + void write(uint8_t v, uint8_t power = 0); + + void write_bytes(const uint8_t *buf, uint16_t count, bool power = 0); + + // Read a byte. + uint8_t read(void); + + void read_bytes(uint8_t *buf, uint16_t count); + + // Write a bit. The bus is always left powered at the end, see + // note in write() about that. + void write_bit(uint8_t v); + + // Read a bit. + uint8_t read_bit(void); + + // Stop forcing power onto the bus. You only need to do this if + // you used the 'power' flag to write() or used a write_bit() call + // and aren't about to do another read or write. You would rather + // not leave this powered if you don't have to, just in case + // someone shorts your bus. + void depower(void); + +#if ONEWIRE_SEARCH + // Clear the search state so that if will start from the beginning again. + void reset_search(); + + // Setup the search to find the device type 'family_code' on the next call + // to search(*newAddr) if it is present. + void target_search(uint8_t family_code); + + // Look for the next device. Returns 1 if a new address has been + // returned. A zero might mean that the bus is shorted, there are + // no devices, or you have already retrieved all of them. It + // might be a good idea to check the CRC to make sure you didn't + // get garbage. The order is deterministic. You will always get + // the same devices in the same order. + uint8_t search(uint8_t *newAddr); +#endif + +#if ONEWIRE_CRC + // Compute a Dallas Semiconductor 8 bit CRC, these are used in the + // ROM and scratchpad registers. + static uint8_t crc8(const uint8_t *addr, uint8_t len); + +#if ONEWIRE_CRC16 + // Compute the 1-Wire CRC16 and compare it against the received CRC. + // Example usage (reading a DS2408): + // // Put everything in a buffer so we can compute the CRC easily. + // uint8_t buf[13]; + // buf[0] = 0xF0; // Read PIO Registers + // buf[1] = 0x88; // LSB address + // buf[2] = 0x00; // MSB address + // WriteBytes(net, buf, 3); // Write 3 cmd bytes + // ReadBytes(net, buf+3, 10); // Read 6 data bytes, 2 0xFF, 2 CRC16 + // if (!CheckCRC16(buf, 11, &buf[11])) { + // // Handle error. + // } + // + // @param input - Array of bytes to checksum. + // @param len - How many bytes to use. + // @param inverted_crc - The two CRC16 bytes in the received data. + // This should just point into the received data, + // *not* at a 16-bit integer. + // @param crc - The crc starting value (optional) + // @return True, iff the CRC matches. + static bool check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc = 0); + + // Compute a Dallas Semiconductor 16 bit CRC. This is required to check + // the integrity of data received from many 1-Wire devices. Note that the + // CRC computed here is *not* what you'll get from the 1-Wire network, + // for two reasons: + // 1) The CRC is transmitted bitwise inverted. + // 2) Depending on the endian-ness of your processor, the binary + // representation of the two-byte return value may have a different + // byte order than the two bytes you get from 1-Wire. + // @param input - Array of bytes to checksum. + // @param len - How many bytes to use. + // @param crc - The crc starting value (optional) + // @return The CRC16, as defined by Dallas Semiconductor. + static uint16_t crc16(const uint8_t* input, uint16_t len, uint16_t crc = 0); +#endif +#endif +}; + +#endif diff --git a/libraries/OneWire/examples/DS18x20_Temperature/DS18x20_Temperature.pde b/libraries/OneWire/examples/DS18x20_Temperature/DS18x20_Temperature.pde new file mode 100644 index 0000000..68ca194 --- /dev/null +++ b/libraries/OneWire/examples/DS18x20_Temperature/DS18x20_Temperature.pde @@ -0,0 +1,112 @@ +#include + +// OneWire DS18S20, DS18B20, DS1822 Temperature Example +// +// http://www.pjrc.com/teensy/td_libs_OneWire.html +// +// The DallasTemperature library can do all this work for you! +// http://milesburton.com/Dallas_Temperature_Control_Library + +OneWire ds(10); // on pin 10 (a 4.7K resistor is necessary) + +void setup(void) { + Serial.begin(9600); +} + +void loop(void) { + byte i; + byte present = 0; + byte type_s; + byte data[12]; + byte addr[8]; + float celsius, fahrenheit; + + if ( !ds.search(addr)) { + Serial.println("No more addresses."); + Serial.println(); + ds.reset_search(); + delay(250); + return; + } + + Serial.print("ROM ="); + for( i = 0; i < 8; i++) { + Serial.write(' '); + Serial.print(addr[i], HEX); + } + + if (OneWire::crc8(addr, 7) != addr[7]) { + Serial.println("CRC is not valid!"); + return; + } + Serial.println(); + + // the first ROM byte indicates which chip + switch (addr[0]) { + case 0x10: + Serial.println(" Chip = DS18S20"); // or old DS1820 + type_s = 1; + break; + case 0x28: + Serial.println(" Chip = DS18B20"); + type_s = 0; + break; + case 0x22: + Serial.println(" Chip = DS1822"); + type_s = 0; + break; + default: + Serial.println("Device is not a DS18x20 family device."); + return; + } + + ds.reset(); + ds.select(addr); + ds.write(0x44, 1); // start conversion, with parasite power on at the end + + delay(1000); // maybe 750ms is enough, maybe not + // we might do a ds.depower() here, but the reset will take care of it. + + present = ds.reset(); + ds.select(addr); + ds.write(0xBE); // Read Scratchpad + + Serial.print(" Data = "); + Serial.print(present, HEX); + Serial.print(" "); + for ( i = 0; i < 9; i++) { // we need 9 bytes + data[i] = ds.read(); + Serial.print(data[i], HEX); + Serial.print(" "); + } + Serial.print(" CRC="); + Serial.print(OneWire::crc8(data, 8), HEX); + Serial.println(); + + // Convert the data to actual temperature + // because the result is a 16 bit signed integer, it should + // be stored to an "int16_t" type, which is always 16 bits + // even when compiled on a 32 bit processor. + int16_t raw = (data[1] << 8) | data[0]; + if (type_s) { + raw = raw << 3; // 9 bit resolution default + if (data[7] == 0x10) { + // "count remain" gives full 12 bit resolution + raw = (raw & 0xFFF0) + 12 - data[6]; + } + } else { + byte cfg = (data[4] & 0x60); + // at lower res, the low bits are undefined, so let's zero them + if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms + else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms + else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms + //// default is 12 bit resolution, 750 ms conversion time + } + celsius = (float)raw / 16.0; + fahrenheit = celsius * 1.8 + 32.0; + Serial.print(" Temperature = "); + Serial.print(celsius); + Serial.print(" Celsius, "); + Serial.print(fahrenheit); + Serial.println(" Fahrenheit"); +} diff --git a/libraries/OneWire/examples/DS2408_Switch/DS2408_Switch.pde b/libraries/OneWire/examples/DS2408_Switch/DS2408_Switch.pde new file mode 100644 index 0000000..d171f9b --- /dev/null +++ b/libraries/OneWire/examples/DS2408_Switch/DS2408_Switch.pde @@ -0,0 +1,77 @@ +#include + +/* + * DS2408 8-Channel Addressable Switch + * + * Writte by Glenn Trewitt, glenn at trewitt dot org + * + * Some notes about the DS2408: + * - Unlike most input/output ports, the DS2408 doesn't have mode bits to + * set whether the pins are input or output. If you issue a read command, + * they're inputs. If you write to them, they're outputs. + * - For reading from a switch, you should use 10K pull-up resisters. + */ + +void PrintBytes(uint8_t* addr, uint8_t count, bool newline=0) { + for (uint8_t i = 0; i < count; i++) { + Serial.print(addr[i]>>4, HEX); + Serial.print(addr[i]&0x0f, HEX); + } + if (newline) + Serial.println(); +} + +void ReadAndReport(OneWire* net, uint8_t* addr) { + Serial.print(" Reading DS2408 "); + PrintBytes(addr, 8); + Serial.println(); + + uint8_t buf[13]; // Put everything in the buffer so we can compute CRC easily. + buf[0] = 0xF0; // Read PIO Registers + buf[1] = 0x88; // LSB address + buf[2] = 0x00; // MSB address + net->write_bytes(buf, 3); + net->read_bytes(buf+3, 10); // 3 cmd bytes, 6 data bytes, 2 0xFF, 2 CRC16 + net->reset(); + + if (!OneWire::check_crc16(buf, 11, &buf[11])) { + Serial.print("CRC failure in DS2408 at "); + PrintBytes(addr, 8, true); + return; + } + Serial.print(" DS2408 data = "); + // First 3 bytes contain command, register address. + Serial.println(buf[3], BIN); +} + +OneWire net(10); // on pin 10 + +void setup(void) { + Serial.begin(9600); +} + +void loop(void) { + byte i; + byte present = 0; + byte addr[8]; + + if (!net.search(addr)) { + Serial.print("No more addresses.\n"); + net.reset_search(); + delay(1000); + return; + } + + if (OneWire::crc8(addr, 7) != addr[7]) { + Serial.print("CRC is not valid!\n"); + return; + } + + if (addr[0] != 0x29) { + PrintBytes(addr, 8); + Serial.print(" is not a DS2408.\n"); + return; + } + + ReadAndReport(&net, addr); +} diff --git a/libraries/OneWire/examples/DS250x_PROM/DS250x_PROM.pde b/libraries/OneWire/examples/DS250x_PROM/DS250x_PROM.pde new file mode 100644 index 0000000..baa51c8 --- /dev/null +++ b/libraries/OneWire/examples/DS250x_PROM/DS250x_PROM.pde @@ -0,0 +1,90 @@ +/* +DS250x add-only programmable memory reader w/SKIP ROM. + + The DS250x is a 512/1024bit add-only PROM(you can add data but cannot change the old one) that's used mainly for device identification purposes + like serial number, mfgr data, unique identifiers, etc. It uses the Maxim 1-wire bus. + + This sketch will use the SKIP ROM function that skips the 1-Wire search phase since we only have one device connected in the bus on digital pin 6. + If more than one device is connected to the bus, it will fail. + Sketch will not verify if device connected is from the DS250x family since the skip rom function effectively skips the family-id byte readout. + thus it is possible to run this sketch with any Maxim OneWire device in which case the command CRC will most likely fail. + Sketch will only read the first page of memory(32bits) starting from the lower address(0000h), if more than 1 device is present, then use the sketch with search functions. + Remember to put a 4.7K pullup resistor between pin 6 and +Vcc + + To change the range or ammount of data to read, simply change the data array size, LSB/MSB addresses and for loop iterations + + This example code is in the public domain and is provided AS-IS. + + Built with Arduino 0022 and PJRC OneWire 2.0 library http://www.pjrc.com/teensy/td_libs_OneWire.html + + created by Guillermo Lovato + march/2011 + + */ + +#include +OneWire ds(6); // OneWire bus on digital pin 6 +void setup() { + Serial.begin (9600); +} + +void loop() { + byte i; // This is for the for loops + boolean present; // device present var + byte data[32]; // container for the data from device + byte leemem[3] = { // array with the commands to initiate a read, DS250x devices expect 3 bytes to start a read: command,LSB&MSB adresses + 0xF0 , 0x00 , 0x00 }; // 0xF0 is the Read Data command, followed by 00h 00h as starting address(the beginning, 0000h) + byte ccrc; // Variable to store the command CRC + byte ccrc_calc; + + present = ds.reset(); // OneWire bus reset, always needed to start operation on the bus, returns a 1/TRUE if there's a device present. + ds.skip(); // Skip ROM search + + if (present == TRUE){ // We only try to read the data if there's a device present + Serial.println("DS250x device present"); + ds.write(leemem[0],1); // Read data command, leave ghost power on + ds.write(leemem[1],1); // LSB starting address, leave ghost power on + ds.write(leemem[2],1); // MSB starting address, leave ghost power on + + ccrc = ds.read(); // DS250x generates a CRC for the command we sent, we assign a read slot and store it's value + ccrc_calc = OneWire::crc8(leemem, 3); // We calculate the CRC of the commands we sent using the library function and store it + + if ( ccrc_calc != ccrc) { // Then we compare it to the value the ds250x calculated, if it fails, we print debug messages and abort + Serial.println("Invalid command CRC!"); + Serial.print("Calculated CRC:"); + Serial.println(ccrc_calc,HEX); // HEX makes it easier to observe and compare + Serial.print("DS250x readback CRC:"); + Serial.println(ccrc,HEX); + return; // Since CRC failed, we abort the rest of the loop and start over + } + Serial.println("Data is: "); // For the printout of the data + for ( i = 0; i < 32; i++) { // Now it's time to read the PROM data itself, each page is 32 bytes so we need 32 read commands + data[i] = ds.read(); // we store each read byte to a different position in the data array + Serial.print(data[i]); // printout in ASCII + Serial.print(" "); // blank space + } + Serial.println(); + delay(5000); // Delay so we don't saturate the serial output + } + else { // Nothing is connected in the bus + Serial.println("Nothing connected"); + delay(3000); + } +} + + + + + + + + + + + + + + + + + diff --git a/libraries/OneWire/keywords.txt b/libraries/OneWire/keywords.txt new file mode 100644 index 0000000..bee5d90 --- /dev/null +++ b/libraries/OneWire/keywords.txt @@ -0,0 +1,38 @@ +####################################### +# Syntax Coloring Map For OneWire +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +OneWire KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +reset KEYWORD2 +write_bit KEYWORD2 +read_bit KEYWORD2 +write KEYWORD2 +write_bytes KEYWORD2 +read KEYWORD2 +read_bytes KEYWORD2 +select KEYWORD2 +skip KEYWORD2 +depower KEYWORD2 +reset_search KEYWORD2 +search KEYWORD2 +crc8 KEYWORD2 +crc16 KEYWORD2 +check_crc16 KEYWORD2 + +####################################### +# Instances (KEYWORD2) +####################################### + + +####################################### +# Constants (LITERAL1) +#######################################