Jump to content
Innovative Marine Aquariums

Arduino Pico Controller


plantarms

Recommended Posts

I also started working on implementing the optical liquid level sensor last night. I have it all coded into my controller and working properly, I just need to build a waterproof housing for it.

 

From my understanding the sensor uses an led and a photo resister inside of a small dome. The photo resister measure the light reflected back off of the inside of the dome and outputs a HIGH signal on the data line when it is in contact with air (high is dry). When the dome is under water however, the reflective index is different and more light escapes from the dome causing the photo resister to switch to LOW (low is wet...not as catchy). I'll let you figure out the rest on how that for an ato application.

 

The reason I'm so excited about this is that there are no moving parts in this optical sensor, so it is much less likely to fail than say a float switch. I've been using the same float switch for over 3 years spliced into pump power cord; just dumb luck that I haven't caused a flood. I'll add some pics soon.

Link to comment
  • Replies 88
  • Created
  • Last Reply
TheUnfocusedOne

I've never really understood the whole Arduino thing.

 

So it's a microprocessor that uses its own unique type of coding? Is there any advantage to doing that instead of just buying a ATMega, learning how to load the boatloader and making up programs in C? I'm genuinely interested. Is the Arduino programming language really intuitive for the processor? I know that writing C programs for a MCU can get pretty hairy at times.

Link to comment

I've never really understood the whole Arduino thing.

 

So it's a microprocessor that uses its own unique type of coding? Is there any advantage to doing that instead of just buying a ATMega, learning how to load the boatloader and making up programs in C? I'm genuinely interested. Is the Arduino programming language really intuitive for the processor? I know that writing C programs for a MCU can get pretty hairy at times.

Yes and no; arduino uses it's own language, however that language is very much based on C. It's pretty simple to learn and use and the coding concepts in arduino are not complicated. I really am not familiar with different microcontrollers as I've only really worked with this one, however the main reason I chose it is because of the online support and simplicity.

 

plantarms

 

Are you using this sensor?https://www.sparkfun.com/products/10221

 

It is water prof.

I am actually using this sensor. It just needs some extra proofing at the base of the wires to make sure the salt doesn't get in anywhere. http://sensing.honeywell.com/product%20page?pr_id=25918

Link to comment

Now try taking code written for the Arduino and convert it for netduino which is based on the MC .NET Framework 4.X and C#.

 

:) Welcome to my world.

 

Plantarms why not build a small glass box and silicone to the out side of the sump or something?

Link to comment

Now try taking code written for the Arduino and convert it for netduino which is based on the MC .NET Framework 4.X and C#.

 

:) Welcome to my world.

 

Plantarms why not build a small glass box and silicone to the out side of the sump or something?

I'm tossing around a few ideas for waterproofing it. One is getting .5'' acrylic and cutting it down to 2'' x 2'' then drilling a hole in the center and a hole down from the top and then adding silicone to seal the wires in. I would also add some strong magnets to that design to mount it like a magnet cleaner or vortech pump.

 

Other thought (easier) was to get a pvc elbow and caps and drill the cutout for the sensor and mount it in the cap, then run the wire up through the top of the elbow and silicone around that. I will probably do this first just so I can get the sensor in place and functioning.

Link to comment
I've never really understood the whole Arduino thing.

 

So it's a microprocessor that uses its own unique type of coding? Is there any advantage to doing that instead of just buying a ATMega, learning how to load the boatloader and making up programs in C? I'm genuinely interested. Is the Arduino programming language really intuitive for the processor? I know that writing C programs for a MCU can get pretty hairy at times.

 

The library's out there are my main reason for using the arduino platform over the bare bones chip, but I'm sure you could get much better efficiency if you web that rout with some bare metal code.

Link to comment

I successfully interfaced the pH probe with my controller last night. I have it now tucked in the back of the tank and it takes a reading every 15 seconds. The code for this took a lot longer than I originally thought as the atlas scientific pH stamp is actually able to run alone without a microcontroller. Interfacing with the arduino requires that you define a second serial port using the SoftwareSerial library and run it at the correct 38400 baud rate. I'm still working out a few kinks in the code, ex: occasionally it returns 0.00 as the pH after it has been pulling correct values previously.

Link to comment

The library's out there are my main reason for using the arduino platform over the bare bones chip, but I'm sure you could get much better efficiency if you web that rout with some bare metal code.

 

I'd say it's not just the libraries, the arduino board is a great little breakout board for the chip and after programming it's easy enough to pull the chip and put it in a dedicated circuit if that's where you're going after your initial prototyping/breadboarding.

 

The arduino environment hides the details of C from you but at the end of the day you're running C code on the microcontroller, there's nothing you can't do.

 

Osric

 

[edit: someone says it's based on C - it isn't just based on C, it is C++ using the gcc toolchain. What they've done is wrap that up in a bunch of preprocessing so that you don't write makefiles or need to #include anything to get started.]

Link to comment

I'd say it's not just the libraries, the arduino board is a great little breakout board for the chip and after programming it's easy enough to pull the chip and put it in a dedicated circuit if that's where you're going after your initial prototyping/breadboarding.

 

The arduino environment hides the details of C from you but at the end of the day you're running C code on the microcontroller, there's nothing you can't do.

 

Osric

 

[edit: someone says it's based on C - it isn't just based on C, it is C++ using the gcc toolchain. What they've done is wrap that up in a bunch of preprocessing so that you don't write makefiles or need to #include anything to get started.]

Hey thanks for all that info. Sounds like you definitely have a better understanding of the lower level functioning of this board

Link to comment

Do you have the code posted?

I am getting into arduino and want to merge your stuff with my lighting controller code.

Link to comment

Here is my current code, it is still in progress at this point

 

//2.7 Gallon Pico Reef LED Light Controller Version 1.13
//Code written by plant_arms 2013-03-10
//Based on various code libraries avalable on the public domain along with coding compiled by the author.
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include "RTClib.h"


//temp sensor vars
#define ONE_WIRE_BUS 3
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress addrZero, addrOne, addrTwo, addrThree;
float tempZero, tempOne, tempTwo, tempThree, avgTemp;
int sensorCount;

//led dimming vars
RTC_DS1307 RTC;
int bluePin = 9;                // blue LEDs connected to digital pin5
int whitePin = 10;               // white LEDs connected to digital pin6
double blueFadeValue = 255;
double whiteFadeValue = 255;
double userWhiteMax =        4;    // maximum percentage intensity of white leds, 0-100 user defined
double userBlueMax =         30;    // maximum percentage intensity of blue leds, 0-100 user defined
double blueMaxPwm;                 // variable used to convert the userBlueMax value into a PWM value
double whiteMaxPwm;                // variable used to convert the userWhiteMax value into a PWM value
int second;
int hour;
int minute; 
int blueLightsOn =         11; //9;      // time of day (hour, 24h clock) to begin blue lights fading on
int whiteLightsOn =        12;//10;      // time of day (hour, 24h clock) to begin white lights fading on
int whiteLightsOff =       20;      // time of day (hour, 24h clock) to begin white lights fading out
int blueLightsOff =        21;      // time of day (hour, 24h clock) to begin blue lights fading out
double fadeTime =          60;      // amount of time in minutes for the fade in/out to last **must be in 60 minute increments** 

//ato vars
int atoPin = 7;

//pH vars
long phReadInterval = 10000; 
long previousMillisPH = 0; 
int PHState = HIGH; 
float PH_Val; 

//default the power switches output
int pwrOne = 53;            //pump
int pwrTwo = 51;            //led lights
int pwrThree = 49;          //led lights
int pwrFour = 47;           //heater  
int pwrFive = 45;           //ato
int pwrSix = 43;            //fuge light
int pwrSeven = 41;          //moonlight
int pwrEight = 39;          //currently empty
 
void setup () {
    Serial.begin(115200);
    Serial3.begin(38400);     //ph stamp
    pinMode(pwrOne, OUTPUT); 
    pinMode(pwrTwo, OUTPUT); 
    pinMode(pwrThree, OUTPUT); 
    pinMode(pwrFour, OUTPUT); 
    pinMode(pwrFive, OUTPUT); 
    pinMode(pwrSix, OUTPUT); 
    pinMode(pwrSeven, OUTPUT); 
    pinMode(pwrEight, OUTPUT); 
    
    Wire.begin();
    RTC.begin();
   if (!RTC.isrunning()) { //uncomment the ! and the //RTC.adjust to be able to reset the datetime value
    // this will allow you to set RTC to the current computer date and time if uncommented and compiled 
    //RTC.adjust(DateTime(__DATE__, __TIME__));
   } 
    sensors.begin();
  
      sensorCount = sensors.getDeviceCount();
      sensors.getAddress(addrZero, 0);
      sensors.getAddress(addrOne, 1);
      sensors.getAddress(addrTwo, 2);
      sensors.getAddress(addrThree, 3);
  
   }

   void loop () {
     power();
     setFade();
     ledRtc();
     sensors.requestTemperatures();
     getTemp();
    // ato();
     pH();
     SerialOut();
                  
   }  
   
 //temporary class to provide power in the power strip   
 void power(){
   digitalWrite(pwrOne, HIGH);
   digitalWrite(pwrTwo, HIGH);
   digitalWrite(pwrThree, HIGH);
   digitalWrite(pwrFour, HIGH);
   digitalWrite(pwrFive, HIGH);  //comment this out once the optical sensor is in place
  // digitalWrite(pwrSix, LOW);
  // digitalWrite(pwrSeven, LOW);
  // digitalWrite(pwrEight, LOW);
 }
 
 //void setFade class used to covert the user percentage input to a PWM value and set to white/blue  
   void setFade(){
     blueMaxPwm = (userBlueMax*2.55);  //converts the user input value (0-100) to a PWM value (0-255)
     whiteMaxPwm = (userWhiteMax*2.55); //converts the user input value (0-100) to a PWM value (0-255)   
   }
    
 
  
 //void ledRtc class to control the leds with the ds1307 timer, absolute value and using the time periods(<= etc) is to gain the correct fade position in case of a power outage
   void ledRtc(){
   
   DateTime now = RTC.now();
   hour = now.hour();
   minute = now.minute();
   second = now.second();
   int totBlueHrOn = hour - blueLightsOn;
   int totBlueHrOff = hour - blueLightsOff;
   int totWhiteHrOn = hour - whiteLightsOn;
   int totWhiteHrOff = hour - whiteLightsOff;
   int totalMinute = minute;
   abs(totBlueHrOn); 
   abs(totBlueHrOff);
   abs(totWhiteHrOn); 
   abs(totWhiteHrOff);
   abs(totalMinute);
   int totalBlueOn   = ((totBlueHrOn*60) + totalMinute);
   int totalBlueOff  = ((totBlueHrOff*60) + totalMinute);
   int totalWhiteOn  = ((totWhiteHrOn*60) + totalMinute);
   int totalWhiteOff = ((totWhiteHrOff*60) + totalMinute);
   
   //fades on blue lights from blueLightsOn through blueLightsOn plus fadeTime and outputs light intensity based on the current time   
   if((hour >= blueLightsOn)&&(hour < (blueLightsOn+(fadeTime/60)))&&(totalBlueOn < fadeTime)){ 
     blueFadeValue = 255-(blueMaxPwm*(totalBlueOn/fadeTime)); 
     analogWrite(bluePin, blueFadeValue);
     digitalWrite(pwrSix, LOW);
     digitalWrite(pwrSeven, LOW);
   }
   
   //fades on white lights from whiteLightsOn to whiteLightsOn plus fadeTime and outputs light intensity based on the current time    
   if((hour >= whiteLightsOn)&&(hour <= (whiteLightsOn+(fadeTime/60)))&&(totalWhiteOn <= fadeTime)){  
     whiteFadeValue = 255-(whiteMaxPwm*(totalWhiteOn/fadeTime)); 
     analogWrite(whitePin, whiteFadeValue);
     digitalWrite(pwrSix, LOW);
     digitalWrite(pwrSeven, LOW);
   }
  
   //puts blue lights up to full if the fade in period is complete and less than bluelightsoff, so full from 10 to 20:59
   if((hour >= (blueLightsOn+(fadeTime/60)))&&(hour < blueLightsOff)){ 
     blueFadeValue = 255-blueMaxPwm;
     analogWrite(bluePin, blueFadeValue);
     digitalWrite(pwrSix, LOW);
     digitalWrite(pwrSeven, LOW);
   }
   
   //puts white lights up to full if the fade in period is complete and less than whitelightsoff, so full from 11 to 19:59
   if((hour >= (whiteLightsOn+(fadeTime/60)))&&(hour < whiteLightsOff)){ 
     whiteFadeValue = 255-whiteMaxPwm;
     analogWrite(whitePin, whiteFadeValue);
     digitalWrite(pwrSix, LOW);
     digitalWrite(pwrSeven, LOW);
   }
   
   //fades out whites from whiteLightsOff to whiteLightsOff plus fadeTime and outputs light intensity based on the current time 
   if((hour >= whiteLightsOff)&&(hour < (whiteLightsOff+(fadeTime/60)))&&(totalWhiteOff <= fadeTime)){ 
     whiteFadeValue = 255-(whiteMaxPwm - (whiteMaxPwm*(totalWhiteOff/fadeTime)));
     analogWrite(whitePin, whiteFadeValue);
     digitalWrite(pwrSix, LOW);
     digitalWrite(pwrSeven, LOW);
   
  }
  //fade out blues from blueLightsOff to blueLightsOff plus fadeTime and outputs light intensity based on the current time
   if((hour >= blueLightsOff)&&(hour < (blueLightsOff+(fadeTime/60)))&&(totalBlueOff <= fadeTime)){
     blueFadeValue = 255-(blueMaxPwm - (blueMaxPwm*(totalBlueOff/fadeTime)));
     analogWrite(bluePin, blueFadeValue);
     digitalWrite(pwrSix, LOW);
     digitalWrite(pwrSeven, LOW);
   
  }
   
   //this sets the white lights to be off from end of whiteLightsOff plus fadeTime to midnight
   if((hour >= (whiteLightsOff+(fadeTime/60))&&(hour <= 24))){  
     whiteFadeValue = 255;
     analogWrite(whitePin, whiteFadeValue);
     digitalWrite(pwrSix, HIGH);
     digitalWrite(pwrSeven, HIGH);
  }  
  
   //this sets the blue lights to be off from end of blueLightsOff plus fadeTime to midnight
   if((hour >= (blueLightsOff+(fadeTime/60))&&(hour < 24))){  
     blueFadeValue = 255;
     analogWrite(bluePin, blueFadeValue);
     digitalWrite(pwrSix, HIGH);
     digitalWrite(pwrSeven, HIGH);
  } 
  
  //this sets the white lights to be off from midnight to whiteLightsOn in case of reset of power outage
   if((hour >= 0)&&(hour < whiteLightsOn)){  
     whiteFadeValue = 255;
     analogWrite(whitePin, whiteFadeValue);
     digitalWrite(pwrSix, HIGH);
     digitalWrite(pwrSeven, HIGH);
   //  digitalWrite(pwrEight, HIGH);
  }  
  
   //this sets the blue lights to be off from midnight to blueLightsOn in case of reset or power outage
   if((hour >= 0)&&(hour < blueLightsOn)){  
     blueFadeValue = 255;
     analogWrite(bluePin, blueFadeValue);
     digitalWrite(pwrSix, HIGH);
     digitalWrite(pwrSeven, HIGH);
    // digitalWrite(pwrEight, HIGH);
  } 
}
      
      
      
 //pulls temp data from the DS18S20 sensors
  void getTemp(){
    
  tempZero = sensors.getTempF(addrZero);
  tempOne = sensors.getTempF(addrOne);
  tempTwo = sensors.getTempF(addrTwo);
  tempThree = sensors.getTempF(addrThree);
  
  //validate the temps before reporting an average to use for other part of the tank
  //if it is lower than 70 or higher than 86 then drop the value
  
  if (tempZero < 70 || tempZero > 86){
   avgTemp = ((tempOne+tempTwo+tempThree)/(sensorCount - 1));}
  else if (tempOne < 70 || tempOne > 86){
   avgTemp = ((tempZero+tempTwo+tempThree)/(sensorCount - 1));}
  else if (tempTwo < 70 || tempTwo > 86){
   avgTemp = ((tempZero+tempOne+tempThree)/(sensorCount - 1));}
  else if (tempThree < 70 || tempThree > 86){ 
   avgTemp = ((tempZero+tempOne+tempTwo)/(sensorCount - 1));}
  else{
   avgTemp = ((tempZero+tempOne+tempTwo+tempThree)/sensorCount);
   } 
  }  
  
 
 
 /*read the optical liquid level sensor and triggers the pump if it changes to air vs water
  void ato(){
 
  int atoValue = digitalRead(atoPin);    //define an input pin to read in the signal from the sensor
  // add code to count the number of seconds per hour it has been on
  if (atoValue == HIGH){
   digitalWrite(pwrFive, HIGH);}
  else{
   digitalWrite(pwrFive, LOW);
  }
 }  
 */
 
 
 
// Get the pH value from the atlas scientific serial stamp
  void pH(){
unsigned long currentMillisPH = millis(); 
  
  if(currentMillisPH - previousMillisPH > phReadInterval) { 
    previousMillisPH = currentMillisPH;   
    if (PHState == HIGH)  { 
        PHState = LOW; 
        } 
    else  { 
        PHState = HIGH; 
        Serial3.print("r\r");  // 'R' reads one value, see stamp doc 
        while (Serial3.available() > 0) { 
            PH_Val = Serial3.parseFloat(); 
            if (Serial3.read() == '\r') { 
            } 
        } 
    } 
  } 
} 


  
 //SerialOut class to output print statements to the serial lcd display, time, temp, and light prcnt
   void SerialOut(){ 
    //DateTime now = RTC.now();
    //print the time pulled in with spaced 0's
    if (hour < 10) {
       Serial.print('0');
       Serial.print(hour);}
     else {Serial.print(hour);}
    Serial.print(':');
    if (minute < 10) {
       Serial.print('0');
       Serial.print(minute);}
     else {Serial.print(minute);}
    Serial.print(':');
    if (second < 10) {
      Serial.print('0');
      Serial.print(second);}
      else { 
    Serial.print(second);}
    Serial.print(" White:");
    Serial.print(100-(whiteFadeValue/2.55));
    Serial.print("%");
    Serial.print(" Blue:");    
     Serial.print(100-(blueFadeValue/2.55));
    Serial.print("% ");
    Serial.print("Temp:");
    Serial.print(avgTemp);
    Serial.print(" pH:");
    Serial.print(PH_Val);  
    Serial.println();
   // delay(1000);
 }  
Link to comment

Archived

This topic is now archived and is closed to further replies.

  • Recommended Discussions


×
×
  • Create New...