Epaperradioram.ino
Jump to navigation
Jump to search
// Copyright 2013 Pervasive Displays, Inc. // Modified for the Fridge Magnet Demo. Renzo Davoli 2013 // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at: // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either // express or implied. See the License for the specific language // governing permissions and limitations under the License. // This program is to illustrate the display operation as described in // the datasheets. The code is in a simple linear fashion and all the // delays are set to maximum, but the SPI clock is set lower than its // limit. Therfore the display sequence will be much slower than // normal and all of the individual display stages be clearly visible // // Embedded Artists has modified Pervasive Display Inc's demo application // to run on the 2.7 inch E-paper Display module (EA-LCD-009 // #include <inttypes.h> #include <ctype.h> #include <SPI.h> #include <Wire.h> #include <EPD.h> #include <LM75A.h> #include <JeeLib.h> #define EPD_SIZE EPD_2_7 // current version number #define DEMO_VERSION "RR" // Arduino IO layout const int Pin_PANEL_ON = 9; // This has been remapped to run on a JeeNode! const int Pin_BORDER = 3; const int Pin_DISCHARGE = 4; const int Pin_PWM = 5; const int Pin_RESET = 6; const int Pin_BUSY = 7; const int Pin_EPD_CS = 8; const int Pin_RED_LED = 13; const int Pin_RAM_CS = 15; // Enable pin for the RAM // LED anode through resistor to I/O pin // LED cathode to Ground #define LED_ON HIGH #define LED_OFF LOW // pre-processor convert to string #define MAKE_STRING1(X) #X #define MAKE_STRING(X) MAKE_STRING1(X) // define the E-Ink display EPD_Class EPD(EPD_SIZE, Pin_PANEL_ON, Pin_BORDER, Pin_DISCHARGE, Pin_PWM, Pin_RESET, Pin_BUSY, Pin_EPD_CS, SPI); LM75A_Class LM75A; //SRAM opcodes #define RDSR 5 #define WRSR 1 #define READ 3 #define WRITE 2 uint8_t SpiRAMRead8(uint16_t address) { uint8_t read_byte; digitalWrite(Pin_RAM_CS, LOW); delayMicroseconds(20); SPI.transfer(READ); SPI.transfer((char)(address >> 8)); SPI.transfer((char)address); read_byte = SPI.transfer(0xFF); digitalWrite(Pin_RAM_CS, HIGH); delayMicroseconds(20); return read_byte; } void SpiRAMRead(void *buffer, uint32_t address, uint16_t length) { uint8_t *p = (uint8_t *)buffer; for (uint16_t i=0; i<length; i++) p[i]=SpiRAMRead8(address+i); } void SpiRAMWrite8(uint16_t address, uint8_t data_byte) { digitalWrite(Pin_RAM_CS, LOW); SPI.transfer(WRITE); SPI.transfer((char)(address >> 8)); SPI.transfer((char)address); SPI.transfer(data_byte); digitalWrite(Pin_RAM_CS, HIGH); } void SpiRAMWrite(void *buffer, uint32_t address, uint16_t length) { uint8_t *p = (uint8_t *)buffer; for (uint16_t i=0; i<length; i++) SpiRAMWrite8(address+i,p[i]); } uint32_t lastupdate; // I/O setup void setup() { pinMode(Pin_RED_LED, OUTPUT); pinMode(Pin_PWM, OUTPUT); pinMode(Pin_BUSY, INPUT); pinMode(Pin_RESET, OUTPUT); pinMode(Pin_PANEL_ON, OUTPUT); pinMode(Pin_DISCHARGE, OUTPUT); pinMode(Pin_BORDER, OUTPUT); pinMode(Pin_EPD_CS, OUTPUT); pinMode(Pin_RAM_CS, OUTPUT); digitalWrite(Pin_RED_LED, LOW); digitalWrite(Pin_PWM, LOW); digitalWrite(Pin_RESET, LOW); digitalWrite(Pin_PANEL_ON, LOW); digitalWrite(Pin_DISCHARGE, LOW); digitalWrite(Pin_BORDER, LOW); digitalWrite(Pin_EPD_CS, HIGH); digitalWrite(Pin_RAM_CS, HIGH); SPI.begin(); SPI.setBitOrder(MSBFIRST); SPI.setDataMode(SPI_MODE0); SPI.setClockDivider(SPI_CLOCK_DIV4); Serial.begin(9600); for (uint32_t i=0; i<5808; i++) SpiRAMWrite8(i,0x00); for (uint32_t i=0; i<5808; i++) SpiRAMWrite8(i+5808,0xaa); #if !defined(__MSP430_CPU__) // wait for USB CDC serial port to connect. Arduino Leonardo only while (!Serial) { } #endif Serial.println(); Serial.println("Demo version: " DEMO_VERSION); Serial.println("Display: " MAKE_STRING(EPD_SIZE)); Serial.println(); lastupdate=0; int temperature = LM75A.read(); Serial.print("Temperature = "); Serial.print(temperature); Serial.println(" Celsius"); EPD.begin(); // power up the EPD panel EPD.setFactor(temperature); // adjust for current temperature EPD.clear(); EPD.end(); // power down the EPD panel // Change the nodeid and group id to support multiple fridge magnets: rf12_initialize(1, RF12_868MHZ, 100); } static int state = 0; // main loop void loop() { uint32_t now = millis(); // check if there is a new packet to receive if (rf12_recvDone() && rf12_crc == 0) { if (rf12_len == 1) { uint8_t buf[33]; uint8_t i; // debugging code: show the contents of a line in RAM SpiRAMRead(buf,rf12_data[0]*33,33); Serial.print("Line "); Serial.print(rf12_data[0]); for (i=0; i<33; i++) { Serial.print(","); Serial.print(buf[i]); } Serial.println('\n'); } else { if (lastupdate == 0) lastupdate=now; SpiRAMWrite((void *)&(rf12_data[1]), rf12_data[0]*33, rf12_len-1); #ifdef DEBUG Serial.print("Packet = "); Serial.println(rf12_len); #endif } } if (lastupdate > 0 && now - lastupdate > 5000) { // five seconds after the first line of a new image arrived // it redraws the display contents // turn off the radio during display refresh (unfortunately the SPI bus is shared rf12_sleep(0); #ifdef DEBUG Serial.print(now); Serial.print("<->"); Serial.println(lastupdate); #endif lastupdate=0; int temperature = LM75A.read(); #ifdef DEBUG Serial.print("Temperature = "); Serial.print(temperature); Serial.println(" Celsius"); #endif EPD.begin(); // power up the EPD panel EPD.setFactor(temperature); // adjust for current temperature //erase the old image EPD.frame_cb_repeat(5808, SpiRAMRead, EPD_compensate); EPD.frame_cb_repeat(5808, SpiRAMRead, EPD_white); //show the new image EPD.frame_cb_repeat(0, SpiRAMRead, EPD_inverse); EPD.frame_cb_repeat(0, SpiRAMRead, EPD_normal); EPD.end(); // power down the EPD panel digitalWrite(Pin_EPD_CS, HIGH); //copy the new image in the old image area for (uint32_t i=0; i<5808; i++) SpiRAMWrite8(i+5808,SpiRAMRead8(i)); //turn on the the rf12 module rf12_sleep(-1); } }