Epaperradioram.ino

Da raspibo.
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);
  }
}