Send mulitple bytes on Wire.receive()

Do you have a question on how to do something.
Ask in here.
Post Reply
User avatar
jsclownfish
Posts: 375
Joined: Mon Oct 24, 2011 7:52 pm
Location: Saint Louis

Send mulitple bytes on Wire.receive()

Post by jsclownfish »

I've been playing with a couple ideas to monitor flow rates and lighting levels. First, I had to figure out how to hook up a second Arduino to the main to see the data output. With your help, I got this to work nicely with a photodiode http://forum.reefangel.com/viewtopic.php?f=19&t=493. I then received a couple of flow meters to try on the same Arduino http://forum.reefangel.com/viewtopic.php?f=4&t=462 to see if I can measure flow. These too look to be working OK on the Arduino and the data can be sent to the main display like the photodiode. However, I haven't had any luck trying hook both up on the same breadboard and display both using the Wire functions. They work on serial display, but I can only get one to work on the main. Any ideas of how to tell the main there are 2 bytes to receive and to display them seperately? I was hoping to use the second board to monitor a few different lighting areas and altleast two water lines, but I have to seperate out the data sent so the display understands each.

Thanks!
-Jon

Here is the current Master pde:

Code: Select all

#include <ReefAngel_Features.h>
#include <ReefAngel_Globals.h>
#include <ReefAngel_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <ReefAngel_EEPROM.h>
#include <ReefAngel_NokiaLCD.h>
#include <ReefAngel_ATO.h>
#include <ReefAngel_Joystick.h>
#include <ReefAngel_LED.h>
#include <ReefAngel_TempSensor.h>
#include <ReefAngel_Relay.h>
#include <ReefAngel_PWM.h>
#include <ReefAngel_Timer.h>
#include <ReefAngel_Memory.h>
#include <ReefAngel.h>
#include <ReefAngel_Colors.h>
#include <ReefAngel_CustomColors.h>
//Actinic and Daylight PMW are on the LED moonlights
byte ActinicPWMValue=0;
byte DaylightPWMValue=0;

#define photodiode 9
byte wmport=Port5;
boolean wmdelay=false;
byte wmpulse=0;

#include <avr/pgmspace.h>
// Labels for the web banner
prog_char id_label[] PROGMEM = "jsclownfish";
prog_char probe1_label[] PROGMEM = "Tank";
prog_char probe2_label[] PROGMEM = "Room";
prog_char probe3_label[] PROGMEM = "Sump";
prog_char relay1_label[] PROGMEM = "Heater1";
prog_char relay2_label[] PROGMEM = "Heater2";
prog_char relay3_label[] PROGMEM = "MHalide";
prog_char relay4_label[] PROGMEM = "Actinic";
prog_char relay5_label[] PROGMEM = "WM1";
prog_char relay6_label[] PROGMEM = "WM2";
prog_char relay7_label[] PROGMEM = "Main";
prog_char relay8_label[] PROGMEM = "Fan";
PROGMEM const char *webbanner_items[] = {
    id_label, probe1_label, probe2_label, probe3_label, relay1_label, relay2_label,
	relay3_label, relay4_label, relay5_label, relay6_label, relay7_label, relay8_label};
void DrawCustomMain()
{
// the graph is drawn/updated when we exit the main menu &
// when the parameters are saved
ReefAngel.LCD.DrawDate(6, 2);
ReefAngel.LCD.Clear(0, 1, 11, 132, 11);
pingSerial();
// Display the Tank temperature with color sensors
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,5,13,"TK:");
  if (ReefAngel.Params.Temp1>830) ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp1, COLOR_RED, 23, 13, 10); 
  else if (ReefAngel.Params.Temp1>810) ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp1, COLOR_ORANGE, 23, 13, 10); 
  else ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp1, COLOR_BLACK, 23, 13, 10);
// Display the Room temperature
ReefAngel.LCD.DrawText(T2TempColor,DefaultBGColor,5,23,"RM:");
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp2, 0, 23, 23, 10);
// Display the Sump temperature
ReefAngel.LCD.DrawText(T3TempColor,DefaultBGColor,5,33,"FL:");
ReefAngel.LCD.DrawSingleMonitor(Wire.receive(), 0, 23, 33, 1);
// Display the PH with color sensors
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor, 64, 13,"PH:");
  if (ReefAngel.Params.PH>840 || ReefAngel.Params.PH<790) ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.PH, COLOR_RED, 82, 13, 100);
  else if (ReefAngel.Params.PH>830 || ReefAngel.Params.PH<800) ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.PH, COLOR_ORANGE, 82, 13, 100);
  else ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.PH, 0, 82, 13, 100);
// Display the % Moonlight
ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 64, 23,"LT:");
ReefAngel.LCD.DrawSingleMonitor(Wire.receive(), 0, 82, 23, 1);
// Display arrows for Wavemaker
ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 64, 33,"WV:");
  if (bitRead(ReefAngel.Relay.RelayData,Port5-1)==1) ReefAngel.LCD.DrawText(APColor,DefaultBGColor, 82, 33,"-->"); //port 5 on
  else if (bitRead(ReefAngel.Relay.RelayData,Port6-1)==1) ReefAngel.LCD.DrawText(APColor,DefaultBGColor, 82, 33,"<--");  //port 6 on
  else ReefAngel.LCD.DrawText(APColor,DefaultBGColor, 82, 33," O "); //port5 and port 6 off, wavemaker delay
pingSerial();
byte TempRelay = ReefAngel.Relay.RelayData;
TempRelay &= ReefAngel.Relay.RelayMaskOff;
TempRelay |= ReefAngel.Relay.RelayMaskOn;
ReefAngel.LCD.DrawOutletBox(12, 45, TempRelay);
//#ifdef RelayExp
// draw 1st expansion relay
//TempRelay = ReefAngel.Relay.RelayDataE[0];
//TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
//TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
//ReefAngel.LCD.DrawOutletBox(12, 55, TempRelay);
//#endif // RelayExp
    int t=ReefAngel.Timer[1].Trigger-now();
    if (t>=0)
    {
      ReefAngel.LCD.Clear(255,105,33,135,43);
      ReefAngel.LCD.DrawText(0, DefaultBGColor,105,33,t);
    }
    if (t>300) ReefAngel.Timer[1].ForceTrigger();  
}
void DrawCustomGraph()
{
ReefAngel.LCD.DrawGraph(1, 75);
}
void setup()
{
  ReefAngel.Init();  //Initialize controller and start web banner timer
  ReefAngel.LoadWebBanner(pgm_read_word(&(webbanner_items[0])), SIZE(webbanner_items));
  ReefAngel.Timer[4].SetInterval(180);  // set interval to 180 seconds
  ReefAngel.Timer[4].Start();
  
  ReefAngel.FeedingModePorts = B00110000;
  ReefAngel.WaterChangePorts = B10110000;
//  ReefAngel.OverheatShutoffPorts = B00000111;
//  ReefAngel.LightsOnPorts = B00001100;
  ReefAngel.Relay.On(Port5);
  ReefAngel.Timer[1].SetInterval(InternalMemory.WM1Timer_read());
  ReefAngel.Timer[1].Start();
  // Ports that are always on
  ReefAngel.Relay.On(Port7);
//  Wire.begin();
//    Serial.begin(9600); // serial connection
}
void loop()
{
  // Specific functions
  //1st Heater at 78.8, 2nd Heater at 77.0, MH on at 10AM off at 8PM, Actinics on at 9AM off at 9PM, Fan kicks on at 82.0
  ReefAngel.StandardHeater(Port1,788,792);
  ReefAngel.StandardHeater(Port2,770,792);
  ReefAngel.MHLights(Port3,10,0,20,0,5);
  ReefAngel.StandardLights(Port4,9,0,21,0);
  ReefAngel.StandardFan(Port8,792,820);
  // Wavemaker Code with night option
  if (ReefAngel.Timer[1].IsTriggered() )
  {
    if ((hour() >= 21) || (hour() <= 8)) //from 9p-Midnight 
    {  //PWMSlope(byte startHour, byte startMinute, byte endHour, byte endMinute, byte startPWM, 
       // byte endPWM, byte Duration, byte oldValue)
      wmpulse=PWMSlope(21,0,8,0,5,30,179,30);
      if (wmdelay)
      {
        ReefAngel.Timer[1].SetInterval(wmpulse);  // WM delay function from 30-170 sec.
        ReefAngel.Timer[1].Start();
        ReefAngel.Relay.Off(Port5);
        ReefAngel.Relay.Off(Port6);
        if (wmport==Port5) wmport=Port6; else wmport=Port5;
        wmdelay=false;
      }
      else
      {
        ReefAngel.Timer[1].SetInterval(200-wmpulse);  // WM bursts timing from 170-30 sec.
        ReefAngel.Timer[1].Start();
        ReefAngel.Relay.On(wmport);
        wmdelay=true;
      }
    }
    else
    {
      //8a-10p normal wave settings
      ReefAngel.Timer[1].SetInterval(InternalMemory.WM1Timer_read());
      ReefAngel.Timer[1].Start();
      ReefAngel.Relay.Toggle(Port5);
      ReefAngel.Relay.Toggle(Port6);
    }
  }
  //Using Daylight ATO high signal piezo buzzer when temp exceeds 83F
  //other options are lowATOpin or the LED pins as ReefAngel.PWM.SetDaylight(100); else ReefAngel.PWM.SetDaylight(0); 
if (ReefAngel.Params.Temp1>830) 
  {
  pinMode(highATOPin,OUTPUT);
  digitalWrite(highATOPin,HIGH);
  }
  else
  {pinMode(highATOPin,OUTPUT);
  digitalWrite(highATOPin,LOW);
  }
    //Moonlight=byte PWMSlope(byte startHour, byte startMinute, byte endHour, byte endMinute, byte startPWM, byte endPWM, byte Duration, byte oldValue)
   ReefAngel.PWM.SetActinic(ActinicPWMValue);
   ActinicPWMValue=PWMSlope(7,00,22,0,0,100,60,ActinicPWMValue); 
   ReefAngel.PWM.SetDaylight(DaylightPWMValue);
   DaylightPWMValue=PWMSlope(7,00,22,0,0,100,60,DaylightPWMValue);
// Web Banner stuff
    if(ReefAngel.Timer[4].IsTriggered())
    {
        ReefAngel.Timer[4].Start();
        ReefAngel.WebBanner();
    }
    {
//receive Light readout
    Wire.requestFrom(photodiode,2);
    }
  ReefAngel.ShowInterface();
}


And here is the slave pde:

Code: Select all

/* Photocell simple testing sketch. 

Connect one end of the photocell to 5V, the other end to Analog 0.
Then connect one end of a 10K resistor from Analog 0 to ground 
Connect LED from pin 11 through a resistor to ground 
For more information see www.ladyada.net/learn/sensors/cds.html */
#include <Wire.h>;        //IC2 communication

int photocellPin = 0;     // the cell and 10K pulldown are connected to a0
int photodiode;     // the analog reading from the sensor divider
int LEDpin = 11;          // connect Red LED to pin 11 (PWM pin)
int LEDbrightness;        // 
int LEDbrightnessinv;
// Define the number of samples to keep track of.  The higher the number,
// the more the readings will be smoothed, but the slower the output will
// respond to the input.  Using a constant rather than a normal variable lets
// use this value to determine the size of the readings array.
const int numReadings = 10;

int readings[numReadings];      // the readings from the analog input
int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
volatile int NbTopsFan; //measuring the rising edges of the signal
int calc;                               
int hallsensor = 2;    //The pin location of the sensor

void rpm ()     //This is the function that the interupt calls 
{ 
  NbTopsFan++;  //This function measures the rising and falling edge of the hall effect sensors signal
} 
void setup() {
  // We'll send debugging information via the Serial monitor
  Serial.begin(9600); 
  Wire.begin(9);                // join i2c bus with address #9
  Wire.onRequest(requestEvent); // register event
    // initialize all the readings to 0: 
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0;
  //flow setup
  pinMode(hallsensor, INPUT); //initializes digital pin 2 as an input
  Serial.begin(9600); //This is the setup function where the serial port is initialised,
  attachInterrupt(0, rpm, RISING); //and the interrupt is attached
} 
void loop() {
  photodiode = analogRead(photocellPin);  
  LEDbrightness = map(photodiode, 0, 1023, 0, 255);
  total= total - readings[index];   // subtract the last reading:         
  readings[index] = LEDbrightness;   // read from the sensor: 
  total= total + readings[index];   // add the reading to the total:       
     index = index + 1;  // advance to the next position in the array:                   
  if (index >= numReadings)     // if we're at the end of the array...           
    index = 0;       // ...wrap around to the beginning:                         
  average = total / numReadings;    // calculate the average:       
  Serial.print("Average byte reading = ");
  Serial.println(average);    // send it to the computer as ASCII digits
//flow calculations  
  NbTopsFan = 0;	//Set NbTops to 0 ready for calculations
  sei();		//Enables interrupts
  delay (1000);	//Wait 1 second
  cli();		//Disable interrupts
  calc = (NbTopsFan * 60 / 7.5); //(Pulse frequency x 60) / 7.5Q, = flow rate in L/hour 
  Serial.print (calc, DEC); //Prints the number calculated above
  Serial.print (" L/hour\r\n"); //Prints "L/hour" and returns a  new line
}
void requestEvent()
{
  delay(500);
  Wire.send(average);   //send info on light reading(may need to be LEDbrightness to keep under 255)
  Wire.send(calc);   //send info on flow meter
}
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Send mulitple bytes on Wire.receive()

Post by rimai »

I think you need to request and immediately grab the 2 incoming numbers right after the request call and store them in a local variable that you could use on the custom display function.
Try this one out and let me know if it works:

Code: Select all

#include <ReefAngel_Features.h>
#include <ReefAngel_Globals.h>
#include <ReefAngel_Wifi.h>
#include <Wire.h>
#include <OneWire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <ReefAngel_EEPROM.h>
#include <ReefAngel_NokiaLCD.h>
#include <ReefAngel_ATO.h>
#include <ReefAngel_Joystick.h>
#include <ReefAngel_LED.h>
#include <ReefAngel_TempSensor.h>
#include <ReefAngel_Relay.h>
#include <ReefAngel_PWM.h>
#include <ReefAngel_Timer.h>
#include <ReefAngel_Memory.h>
#include <ReefAngel.h>
#include <ReefAngel_Colors.h>
#include <ReefAngel_CustomColors.h>
//Actinic and Daylight PMW are on the LED moonlights
byte ActinicPWMValue=0;
byte DaylightPWMValue=0;

#define photodiode 9
byte wmport=Port5;
boolean wmdelay=false;
byte wmpulse=0;
byte brightness=0;
byte flow=0;

#include <avr/pgmspace.h>
// Labels for the web banner
prog_char id_label[] PROGMEM = "jsclownfish";
prog_char probe1_label[] PROGMEM = "Tank";
prog_char probe2_label[] PROGMEM = "Room";
prog_char probe3_label[] PROGMEM = "Sump";
prog_char relay1_label[] PROGMEM = "Heater1";
prog_char relay2_label[] PROGMEM = "Heater2";
prog_char relay3_label[] PROGMEM = "MHalide";
prog_char relay4_label[] PROGMEM = "Actinic";
prog_char relay5_label[] PROGMEM = "WM1";
prog_char relay6_label[] PROGMEM = "WM2";
prog_char relay7_label[] PROGMEM = "Main";
prog_char relay8_label[] PROGMEM = "Fan";
PROGMEM const char *webbanner_items[] = {
    id_label, probe1_label, probe2_label, probe3_label, relay1_label, relay2_label,
   relay3_label, relay4_label, relay5_label, relay6_label, relay7_label, relay8_label};
void DrawCustomMain()
{
// the graph is drawn/updated when we exit the main menu &
// when the parameters are saved
ReefAngel.LCD.DrawDate(6, 2);
ReefAngel.LCD.Clear(0, 1, 11, 132, 11);
pingSerial();
// Display the Tank temperature with color sensors
ReefAngel.LCD.DrawText(T1TempColor,DefaultBGColor,5,13,"TK:");
  if (ReefAngel.Params.Temp1>830) ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp1, COLOR_RED, 23, 13, 10); 
  else if (ReefAngel.Params.Temp1>810) ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp1, COLOR_ORANGE, 23, 13, 10); 
  else ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp1, COLOR_BLACK, 23, 13, 10);
// Display the Room temperature
ReefAngel.LCD.DrawText(T2TempColor,DefaultBGColor,5,23,"RM:");
ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.Temp2, 0, 23, 23, 10);
// Display the Sump temperature
ReefAngel.LCD.DrawText(T3TempColor,DefaultBGColor,5,33,"FL:");
ReefAngel.LCD.DrawSingleMonitor(flow, 0, 23, 33, 1);
// Display the PH with color sensors
ReefAngel.LCD.DrawText(PHColor,DefaultBGColor, 64, 13,"PH:");
  if (ReefAngel.Params.PH>840 || ReefAngel.Params.PH<790) ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.PH, COLOR_RED, 82, 13, 100);
  else if (ReefAngel.Params.PH>830 || ReefAngel.Params.PH<800) ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.PH, COLOR_ORANGE, 82, 13, 100);
  else ReefAngel.LCD.DrawSingleMonitor(ReefAngel.Params.PH, 0, 82, 13, 100);
// Display the % Moonlight
ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 64, 23,"LT:");
ReefAngel.LCD.DrawSingleMonitor(brightness, 0, 82, 23, 1);
// Display arrows for Wavemaker
ReefAngel.LCD.DrawText(DPColor,DefaultBGColor, 64, 33,"WV:");
  if (bitRead(ReefAngel.Relay.RelayData,Port5-1)==1) ReefAngel.LCD.DrawText(APColor,DefaultBGColor, 82, 33,"-->"); //port 5 on
  else if (bitRead(ReefAngel.Relay.RelayData,Port6-1)==1) ReefAngel.LCD.DrawText(APColor,DefaultBGColor, 82, 33,"<--");  //port 6 on
  else ReefAngel.LCD.DrawText(APColor,DefaultBGColor, 82, 33," O "); //port5 and port 6 off, wavemaker delay
pingSerial();
byte TempRelay = ReefAngel.Relay.RelayData;
TempRelay &= ReefAngel.Relay.RelayMaskOff;
TempRelay |= ReefAngel.Relay.RelayMaskOn;
ReefAngel.LCD.DrawOutletBox(12, 45, TempRelay);
//#ifdef RelayExp
// draw 1st expansion relay
//TempRelay = ReefAngel.Relay.RelayDataE[0];
//TempRelay &= ReefAngel.Relay.RelayMaskOffE[0];
//TempRelay |= ReefAngel.Relay.RelayMaskOnE[0];
//ReefAngel.LCD.DrawOutletBox(12, 55, TempRelay);
//#endif // RelayExp
    int t=ReefAngel.Timer[1].Trigger-now();
    if (t>=0)
    {
      ReefAngel.LCD.Clear(255,105,33,135,43);
      ReefAngel.LCD.DrawText(0, DefaultBGColor,105,33,t);
    }
    if (t>300) ReefAngel.Timer[1].ForceTrigger();  
}
void DrawCustomGraph()
{
ReefAngel.LCD.DrawGraph(1, 75);
}
void setup()
{
  ReefAngel.Init();  //Initialize controller and start web banner timer
  ReefAngel.LoadWebBanner(pgm_read_word(&(webbanner_items[0])), SIZE(webbanner_items));
  ReefAngel.Timer[4].SetInterval(180);  // set interval to 180 seconds
  ReefAngel.Timer[4].Start();
  
  ReefAngel.FeedingModePorts = B00110000;
  ReefAngel.WaterChangePorts = B10110000;
//  ReefAngel.OverheatShutoffPorts = B00000111;
//  ReefAngel.LightsOnPorts = B00001100;
  ReefAngel.Relay.On(Port5);
  ReefAngel.Timer[1].SetInterval(InternalMemory.WM1Timer_read());
  ReefAngel.Timer[1].Start();
  // Ports that are always on
  ReefAngel.Relay.On(Port7);
//  Wire.begin();
//    Serial.begin(9600); // serial connection
}
void loop()
{
  // Specific functions
  //1st Heater at 78.8, 2nd Heater at 77.0, MH on at 10AM off at 8PM, Actinics on at 9AM off at 9PM, Fan kicks on at 82.0
  ReefAngel.StandardHeater(Port1,788,792);
  ReefAngel.StandardHeater(Port2,770,792);
  ReefAngel.MHLights(Port3,10,0,20,0,5);
  ReefAngel.StandardLights(Port4,9,0,21,0);
  ReefAngel.StandardFan(Port8,792,820);
  // Wavemaker Code with night option
  if (ReefAngel.Timer[1].IsTriggered() )
  {
    if ((hour() >= 21) || (hour() <= 8)) //from 9p-Midnight 
    {  //PWMSlope(byte startHour, byte startMinute, byte endHour, byte endMinute, byte startPWM, 
       // byte endPWM, byte Duration, byte oldValue)
      wmpulse=PWMSlope(21,0,8,0,5,30,179,30);
      if (wmdelay)
      {
        ReefAngel.Timer[1].SetInterval(wmpulse);  // WM delay function from 30-170 sec.
        ReefAngel.Timer[1].Start();
        ReefAngel.Relay.Off(Port5);
        ReefAngel.Relay.Off(Port6);
        if (wmport==Port5) wmport=Port6; else wmport=Port5;
        wmdelay=false;
      }
      else
      {
        ReefAngel.Timer[1].SetInterval(200-wmpulse);  // WM bursts timing from 170-30 sec.
        ReefAngel.Timer[1].Start();
        ReefAngel.Relay.On(wmport);
        wmdelay=true;
      }
    }
    else
    {
      //8a-10p normal wave settings
      ReefAngel.Timer[1].SetInterval(InternalMemory.WM1Timer_read());
      ReefAngel.Timer[1].Start();
      ReefAngel.Relay.Toggle(Port5);
      ReefAngel.Relay.Toggle(Port6);
    }
  }
  //Using Daylight ATO high signal piezo buzzer when temp exceeds 83F
  //other options are lowATOpin or the LED pins as ReefAngel.PWM.SetDaylight(100); else ReefAngel.PWM.SetDaylight(0); 
if (ReefAngel.Params.Temp1>830) 
  {
  pinMode(highATOPin,OUTPUT);
  digitalWrite(highATOPin,HIGH);
  }
  else
  {pinMode(highATOPin,OUTPUT);
  digitalWrite(highATOPin,LOW);
  }
    //Moonlight=byte PWMSlope(byte startHour, byte startMinute, byte endHour, byte endMinute, byte startPWM, byte endPWM, byte Duration, byte oldValue)
   ReefAngel.PWM.SetActinic(ActinicPWMValue);
   ActinicPWMValue=PWMSlope(7,00,22,0,0,100,60,ActinicPWMValue); 
   ReefAngel.PWM.SetDaylight(DaylightPWMValue);
   DaylightPWMValue=PWMSlope(7,00,22,0,0,100,60,DaylightPWMValue);
// Web Banner stuff
    if(ReefAngel.Timer[4].IsTriggered())
    {
        ReefAngel.Timer[4].Start();
        ReefAngel.WebBanner();
    }
    {
//receive Light readout
    Wire.requestFrom(photodiode,2);
    if (Wire.available())
    {
      brightness=Wire.receive();
      flow=Wire.receive();
    }
  ReefAngel.ShowInterface();
}

Roberto.
User avatar
jsclownfish
Posts: 375
Joined: Mon Oct 24, 2011 7:52 pm
Location: Saint Louis

Re: Send mulitple bytes on Wire.receive()

Post by jsclownfish »

Something is still not in sync with the data packet. I simplified the slave to just send a fixed number for each measure to try and diagnose the issue. I always get the last byte sent (in this case 110) into the first local variable. The other will display 255.
-Jon

Here is the simplified slave protocol:

Code: Select all

#include <Wire.h>;        //IC2 communication

int flowspeed;
int lightlevel;

void setup() {
  Wire.begin(9);                // join i2c bus with address #9
  Wire.onRequest(requestEvent); // register event
} 
void loop() {
  flowspeed = 105; //number to represent flow
  lightlevel = 110;//number to represent light
}
void requestEvent()
{
  Wire.send(flowspeed);   //send info on flow
  Wire.send(lightlevel);   //send info on light
}
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Send mulitple bytes on Wire.receive()

Post by rimai »

Code: Select all

      brightness=Wire.receive();
      flow=Wire.receive();
The RA is expecting brightness and then flow.

Code: Select all

  Wire.send(flowspeed);   //send info on flow
  Wire.send(lightlevel);   //send info on light
You are sending flow and then lightlevel.

But I don't think this is the problem. I have to test it out to make sure we can send 2 bytes at a time. I never had to send 2 bytes on requestEvent(). I've sent several bytes with receiveEvent() though.
Roberto.
User avatar
jsclownfish
Posts: 375
Joined: Mon Oct 24, 2011 7:52 pm
Location: Saint Louis

Re: Send mulitple bytes on Wire.receive()

Post by jsclownfish »

Yes, you're correct. I was switching them around to see if it changed anything, but I always get one to report at the first wire.receive() variable but 255 at the second wire.receive() variable. I tried to find an example on the forum where the PWM extension channel levels were reported on the custom main, but the example I found doesn't seem to work that way.

Jon
User avatar
jsclownfish
Posts: 375
Joined: Mon Oct 24, 2011 7:52 pm
Location: Saint Louis

Re: Send mulitple bytes on Wire.receive()

Post by jsclownfish »

I got it to work! :D I changed this piece of the slave pde from this...

Code: Select all

void requestEvent()
{
  Wire.send(flowspeed);   //send info on flow
  Wire.send(lightlevel);   //send info on light
}
to this....

Code: Select all

void requestEvent()
{
  byte output[] ={flowspeed,lightlevel};
  Wire.send(output,2);   //send info on both light and flow
Now it seems to work with both the test file and the original monitors (water flow and light). Thanks for your help!
-Jon
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Send mulitple bytes on Wire.receive()

Post by rimai »

Awesome!!!
Roberto.
User avatar
jsclownfish
Posts: 375
Joined: Mon Oct 24, 2011 7:52 pm
Location: Saint Louis

Re: Send mulitple bytes on Wire.receive()

Post by jsclownfish »

My next step is to be able to see the values from the light sensor and flow meters away from home (LCD screen). I suppose this is similar to the salinity and temperature functions, but I don't know how to go about it. How do I go about sending the values over the wifi to access away from home? Can I need to put it into memory and look for it using one of the tools already built?

Thanks,

Jon
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Send mulitple bytes on Wire.receive()

Post by rimai »

Humm..
It's not possible at the moment without changing core files of the libraries.
Although the idea of saving into internal memory and reading it through wifi does work, you have a limitation on the number of times you can save stuff to your internal memory. 100000 times is what the manufacturer speced.
Roberto.
User avatar
jsclownfish
Posts: 375
Joined: Mon Oct 24, 2011 7:52 pm
Location: Saint Louis

Re: Send mulitple bytes on Wire.receive()

Post by jsclownfish »

Bummer. There are a few things I'd like to try out (light sensors, flow sensors, water detector, power outage alert) and I think all are possible but are most beneficial when the data can be seen away from the tank for alerts and such. I don't have the skills to build software to send alerts or reprocess the data, but it would be nice to have a way to regularly update the status of these new measures so you could query the system to see if things are in check. I guess if I could limit the number of times data gets sent to internal memory or only to write if data exceeds specs, maybe I could keep the number down, but I'd rather not go that route. Is it possible to have an editable library for 'other' data similar to the salinity or temp module? or do they tie in to other libraries that would need editing as well?

Thanks,
Jon
rimai
Posts: 12857
Joined: Fri Mar 18, 2011 6:47 pm

Re: Send mulitple bytes on Wire.receive()

Post by rimai »

I did think about having a custom field option, but never got around into planning anything.
I have been testing a new place to check your RA data, which will be integrated with this forum website, over the past several months and I realized today that I've been wasting a lot of storage.
So, I'm going to need to start planning on restructuring the database and will definitely keep this in mind.
It'll get there in time. :)
Roberto.
Post Reply