Show Posts
Pages: [1]
1  Forum 2005-2010 (read only) / Interfacing / Re: PCRJ 8x24 LCD on: January 15, 2010, 06:33:59 pm
Yeah, the 5V serial is why I picked this LCD; thought it would be simple.

I've gotten the board powered up, not sure about the -9V, as there is a voltage regulator via pin 16, I just feed it 12V.  I get how to hook it up, confusing as it was for me, I got through that, at least in rough form.

My question is with the software side, I'm guessing I should write a library for communication with this board.
2  Forum 2005-2010 (read only) / Interfacing / Re: PCRJ 8x24 LCD on: January 15, 2010, 02:30:01 pm
Another link with more info on the LCD :
http://www.btinternet.com/~markd833/LCD/intro.htm

Thanks for any help!!
3  Forum 2005-2010 (read only) / Interfacing / Re: PCRJ 8x24 LCD on: January 15, 2010, 02:26:20 pm
I am very much a beginner with electronics as a whole, much less the arduino, however, I'm making a go at it!  ;-)  I'm planning on using this LCD :

http://www.pjrc.com/store/mp3_display.html

They have helpfully supplied this info :

http://www.pjrc.com/tech/mp3/lcd_protocol.html

But I'm a bit at a loss as to where to start!  It looks to me to be a simple serial communication deal, but as I've never really programmed before this, so I could use some direction.  I figure I need to adapt http://www.arduino.cc/playground/Learning/SerialLCD to the commands my LCD understands.

I've got my project hosted at Google, explanations under the wiki tab.

http://code.google.com/p/atmega328growcontroller/

Where should I start?  I'm a self taught beginner, so I'm very open to all comments, suggestions, whatever.
4  Forum 2005-2010 (read only) / Interfacing / PCRJ 8x24 LCD on: January 15, 2010, 02:25:54 pm
I purchased one of these LCDs from ebay, and I'm wondering how to interface with my arduino.  Sorry about this short post, I need to get past the 1 post limit for links.  smiley-wink
5  Forum 2005-2010 (read only) / Development / Re: Parts Vendors Sorted By Low/Free Shipping Cost on: April 08, 2010, 08:29:37 pm
Yeah, I thought it was crazy, too.  After I sent them an email, they dropped the socket off the list and mailed out the rest today.  I can't wait to get it, the CO2 sensor they have is the cheapest I've found around, nobody else sells this by itself.  Other than poor English (which I find mildly amusing, not annoying) they've been friendly and seem to want to help.  Not sure why I would have wanted it held that long, though I really would have liked the socket.

Mine shipped with a Hong Kong post confirmation number, not Thai, too.  I've heard they have multiple warehouses, so maybe it's luck of the draw.
6  Forum 2005-2010 (read only) / Development / Re: Parts Vendors Sorted By Low/Free Shipping Cost on: April 07, 2010, 12:03:44 pm
Here's my current experience with Futurlec...  I placed an order Mar 25 for a bunch of stuff (headers, a PIR sensor, a few photo-transistors, a few AtTinys... just random stuff) with the main goal of getting the CO2 sensor they have, a total of ~ $100.  I'm a patient guy, so I waited until Mon (4/5) to shoot them an email asking for a status update.  They said:
Quote
Dear Matt
 
Only Gas Sensor Socket is unavailable from your order and is currently out of stock.
 
A new shipment will arrive at our warehouse on June when we will be able to dispatch your order.
 
 
Should you have any further enquiry, please feel free to contact us.
 
Best Regards
Amp
Futurlec
www.futurlec.com

Not sure what they were thinking here, I guess they were going to hold up my order for 2 months just because they were short a socket.  Without consulting me first.  Craziness.  I did some research on them beforehand, so I knew to expect long waits, but jeez, that's BEFORE mailtime.  Keep it in mind.

I buy tons of stuff off ebay, basic ICs, transistors, (not caps or resistors, I've found better deals buying by the 100 alongside an order from a supplyhouse) most of the basics.  A lot of times it's only $3 or $4 for 10, 25, or 100 of whatever item you want w/ shipping included.  China, Hong Kong, even Thailand usually ships to me (NE USA) in two weeks, sometimes less.  I think the tiny package size speeds things up.  Buying it singly from a supplier would be cheaper if not for the shipping, except I find that having spares of everything outweighs that.
7  Forum 2005-2010 (read only) / Interfacing / Re: interfacing PPM / TDS probe to arduino on: January 09, 2011, 04:07:15 am
Here is a good link on how the probe works, creating your own EC probe and interfacing it with your ADC:

http://blea.ch/wiki/index.php/PPM_Meter
http://www.docstoc.com/docs/68219669/BATTERY-POWERED-COST-EFFECTIVE-TDS-LOGGER-INTENDED-FOR-WATER-TESTING  <~ Advanced,  no good to the original poster, but a fun read.  This guy has a great idea, measuring how long it takes a capacitor to drain through the water.

More info on the terms TDS vs PPM vs EC:

http://www.hydroponics.net/learn/debate_over_ec_and_tds.asp
http://www.nuganics.com.au/faq/ec-%E2%80%93-tds-general-information-sheet/

Now while a commercial probe alone can cost over $100, you can get a simple cheapo PPM meter from eBay (item#180583399534, or http://goo.gl/sEd2t) for <$15!  Hacking one of those in half and just using the probe might save you some time/effort.  That phidgets pH/ORP thing works great, too, by the way.
8  Forum 2005-2010 (read only) / Interfacing / Re: Help with CO2 sensor hookup on: January 31, 2010, 10:44:30 pm
jluciani ~ not sure what you mean by .5% - 1%, are you referring to CO2 concentration, I'm trying to differentiate with a resolution of 50 ppm minumum, which is .005%!  I'm designing a CO2 controller that will be used in a greenhouse to take the ambient CO2 from 300PPM to 2000PPM, so I'm looking at a fairly narrow range.  I'm also thinking I'll need at least one full step of resolution in between the trigger level and releasing the trigger, and as one of the goals here is to maintain as stable of an environment as possible, I want this to be as small as possible.

If I get what you mean by '100x' 'instrumental amplifier', that's what I was leaning towards; I ordered a 10 pack of TL062 the other day for the pH probe I'm also going to try and cobble together.  I have an inkling of how to use these, but no experience with them yet.

I briefly looked into those two sites, but instantly I was turned off by appliedsensor's front page "We'll use our intellectual property, proprietary software tools" ... yeah, no.  smiley-wink   I'm trying to make this as open source as possible; that phrase just turns me off.  e2v looks a little more promising... even though some of their documentation says for IR11BR it measures between 0% and 100%, in the
more generic datasheet that covered the whole product range stated the IR11BD and IR21DB sensed 0-3000PPM,0-2.0% vol, and 0-5.0% vol... that might need a little further investigation, but for now, I think the sensor from Futurlec (MG811) will work fine.

retrolefty ~ "Use the analogReference(INTERNAL) command to make the Arduino measurement range around 0- 1.1vdc. This would give you around one step per millivolt resolution.  http://arduino.cc/en/Reference/AnalogReference"

Thank you!!!  If my math is correct, with a difference of 1700PPM being represented by a change of 39mV, a 1mV resolution would equal around 45 PPM per step.  Still a little higher than I would like, but hey, this will work!
9  Forum 2005-2010 (read only) / Interfacing / Re: Help with CO2 sensor hookup on: January 31, 2010, 05:46:15 pm
I'm very new to the electronics scene here, but this particular part is of interest to me, as I'm planning on incorporating it into my project as well.  To me, it appears A is connected to GND while B gives a mV level charge.

I could be reading that chart wrong, totally possible here, but it looks like  at 300 PPM (normal outdoor air level) it has a voltage of 325 mV and at 2000 PPM (as high as I need it) it will read 286mV, a difference of only 39 mV!!  With the arduino's 4.88 mV resolution, that's only ~ 8 steps total.  My thinking is correct here, right?  Not sure if this will work for you, it's not enough for me.

I'm working on other aspects of my project at the moment, but at the moment I think that either a higher resolution A/D converter (ADS1286PB??) or an op-amp would work to take this output to something more useful.  I know this post is a bit old, but then if you've figured out how to use it, I want to hear it!
10  Forum 2005-2010 (read only) / Interfacing / Re: Moisture meter input on: May 02, 2010, 07:17:22 am
I see a couple different ways you could do this:

A phototransistor taped over the LED on the probe, set to send 5V whenever it senses light.  I've seen this on home energy monitoring systems, where the meter has an LED that blinks every 1KwH.  This would allow you to keep your probe intact.  
http://www.secretbatcave.co.uk/electronics/arduino/arduino-house-monitor.html  
http://offog.org/code/electricity.html

Rip the probe apart, and interface directly with the signal turning on that LED.

Rip the probe apart, and try to figure out what's going on in there.  There should be some sort of voltage sensing circuitry in there, it may be possible to adapt it to work with the Arduino.  I suspect (because you're asking here) that this is more technical of a solution than you wanted.

Create your own soil probes.  Depending on what you've got lying around, this may be an easy solution.  It would also allow you to test more than one location.  
http://www.cheapvegetablegardener.com/2009/11/how-to-make-cheap-soil-moisture-sensor-2.html

Personally, I don't like the idea of sticking one of those 2-prong probes into the grow medium and leaving that there for extended periods of time.  I think that as water comes and goes and things naturally shift, the medium will adjust itself to the probes, leading to a sample that may not be representative of the whole area.
11  Forum 2005-2010 (read only) / Exhibition / Re: Greenhouse controller v0.4 on: February 14, 2010, 08:07:59 am
Nope, hydroponic, but post it anyway.  Maybe somebody else can use it.

I'm interested in what people think of the code.  
12  Forum 2005-2010 (read only) / Exhibition / Re: Greenhouse controller v0.4 on: February 12, 2010, 02:38:44 pm
Quote
/*
 *  A library for printing to a 8x20 LCD, obtained from PJRC
 *  Created by MulletSoda, 2010
 *  With love!
 */

#ifndef PrintPJRClcd_h
#define PrintPJRClcd_h

#include "WProgram.h"

class PrintPJRClcd
{

public:
  /* Variables */
  int blank;
  /* Functions */
  PrintPJRClcd(); //initialize, clear screen, set up all descriptive info
  void PrintData(int type,unsigned long datas);//type is set to location, datas is info to be printed
  void RedrawScreen();
private:
  /* Variables */
  int _row; //Cursor row position, 1 - 8
  int _column; //Cursor column position, 1 - 20
  /* Functions */
  void PositionCursor(int _row, int _cursor); //position cursor
};


#endif


Quote
#include "WProgram.h"
#include "PrintPJRClcd.h"

PrintPJRClcd::PrintPJRClcd()
{

};

void PrintPJRClcd::RedrawScreen()
{
  PositionCursor(1,1);
  Serial.print("Air T:   F      My Robot");
  PositionCursor(2,1);
  Serial.print("Rez1 T:   F       Friend");
  PositionCursor(4,1);
  Serial.print("Pump1:    :      seconds");
  PositionCursor(3,1);
  Serial.print("                        ");
  PositionCursor(5,1);
  Serial.print("                        ");
  PositionCursor(6,1);
  Serial.print("Worklight:               ");
  PositionCursor(7,1);
  Serial.print("            Min left     ");
  PositionCursor(8,1);
  Serial.print("                   ");

};

void PrintPJRClcd::PositionCursor(int _row, int _column)
{
  Serial.write(0x5C);
  Serial.write(0x42);
  Serial.write(byte(_column+31));
  Serial.write(byte(_row+31));
};

void PrintPJRClcd::PrintData(int type, unsigned long datas)
{

  switch (type) //where does this data go?
  {
  case 0: //Air temp
    PositionCursor(1,8);
    Serial.print(datas);
    break;
  case 1: //Rez temp
    PositionCursor(2,9);
    Serial.print(datas);
    break;
  case 2: //Pump1 on or off
    PositionCursor(4,8);
    if(datas==0) Serial.print("Off");
    else if(datas==1) Serial.print("On ");
  case 3: // Minutes left on Pump1
    PositionCursor(4,13);
    Serial.print(datas);
    break;
  case 4: //Day or Night
    PositionCursor(7,1);
    if(datas==0) Serial.print("Night");
    else if(datas==1) Serial.print(" Day ");
    break;
  case 5: // Min left till change
    PositionCursor(7,7);
    Serial.print(datas);
    break;
  case 6: //worklight status
    PositionCursor(6,12);
    if(datas==4) Serial.print("Off  ");
    if(datas==5) Serial.print("On   ");
    break;
  case 7: //debug
    PositionCursor(5,2);
    Serial.print(datas);
    break;
  };
};

13  Forum 2005-2010 (read only) / Exhibition / Re: Greenhouse controller v0.4 on: February 12, 2010, 02:34:47 pm
Quote
/*
 *  A timer for controlling outlets
 *  Created by MulletSoda, 2010
 *  With love!
 */

#ifndef OutletTimer_h
#define OutletTimer_h

#include "WProgram.h"

class OutletTimer
{
public: //publicly accessable variables and functions

  int pinNumber; //0 - 255, pin number of outlet
  unsigned long MaintTime; //   Maintainence mode time, turns on/off for a set period of time then returns to normal functioning
  int CurrentMode; //the current mode of this outlet
  unsigned long TimeLeft; //milliseconds until mode change
  unsigned long OffDuration; //Time outlet remains off
  unsigned long OnDuration; //Time outlet remains on

  /*  Functions available to the public */

  OutletTimer(int _pinNumber, int _InitialMode, unsigned int _InitialTimeSec);
  void ElapseTime(int TimeSinceLast); //De-increment time remaining
  void ChangeMode(int NewMode); //force a mode change
private: //private, localized variables and functions
  int _pinNumber;
  int _InitialMode;
  int _InitialTimeSec;

};

#endif




Quote
#include "WProgram.h"
#include "OutletTimer.h"

OutletTimer::OutletTimer(int _pinNumber, int _InitialMode, unsigned int _InitialTimeSec)
{
  /*  This should do everything needed when the controller first starts up
   *  Initialize pin, set pin to whatever, set on time, set off time, set timeleft, set mode,
   *  
   */
  pinNumber=_pinNumber;
  pinMode(pinNumber, OUTPUT);
  digitalWrite(pinNumber, _InitialMode);
  TimeLeft = _InitialTimeSec * 1000.0;          //set TimeLeft
  CurrentMode = int(_InitialMode);
}

void OutletTimer::ElapseTime(int TimeSinceLast)
{
  //increment time down, this includes check for 0 time and TimeIsUp

  if (TimeLeft > 1000.0) TimeLeft-=TimeSinceLast;  //time slips away yet again
  if (TimeLeft <= 1000.0 && TimeLeft != 0.0) //if TimeIsUp but not disabled
  {
    switch (CurrentMode) //what's the current mode we're switching from?
    {
      case (0): //outlet off, normal op: turn mode to on, time to OnTime, turn pin high
      ChangeMode(1);
      break;
      case (1): //outlet on, normal op : mode off, time to OffTime, pin low
      ChangeMode(0);
      break; 
      case (2): //maint off time up, return to normal operation: turn mode to on, time to OnTime, turn pin high
      ChangeMode(1);
      break;
      case (3): //maint on time up, return normal op : turn mode off, time to OffTime, pin low
      ChangeMode(0);
      break; 
      case (4): //perm off, should NEVER get here
      break;
      case (5): //perm on, should NEVER get here
      break; 

    }
    //for some reason I needed a delay here before, if there are errors, try adding 2ms
  }
}

void OutletTimer::ChangeMode(int NewMode)
{
  //mode change, newMode can be used to pass button presses, too, by using higher NewMode values
  switch (NewMode)
  {
  case 0: //off
    digitalWrite(pinNumber, LOW);
    CurrentMode = 0;
    TimeLeft = OffDuration * 1000.0;
    break;
  case 1: //on
    digitalWrite(pinNumber, HIGH);
    CurrentMode = 1;
    TimeLeft = OnDuration * 1000.0;
    break;
  case 2://off maint
    digitalWrite(pinNumber, LOW);
    CurrentMode = 2;
    TimeLeft=MaintTime * 1000.0;
    break;
  case 3://on maint
    CurrentMode = 3;
    digitalWrite(pinNumber, HIGH);
    TimeLeft = MaintTime * 1000.0;
    break;
  case 4://perm off
    digitalWrite(pinNumber, LOW);
    CurrentMode = 4;
    TimeLeft = 0.0;
    break;
  case 5://perm on
    digitalWrite(pinNumber, HIGH);
    CurrentMode = 5;
    TimeLeft = 0.0;
    break;
  default: //other
    digitalWrite(pinNumber, LOW);
    /*
            *  This will be used to deal with button presses later.  Example :
                  * Button0 gets pressed, can be sent as NewMode==50, then a switch (CurrentMode)
                  * {case 0: //toggle mode to on; case 1: //toggle mode to off}
                  */
    break;

  }
}
14  Forum 2005-2010 (read only) / Exhibition / Greenhouse controller v0.4 on: February 12, 2010, 02:33:56 pm
This is my first project with the arduino, and I know, I jumped right in.  This is a pretty big project for a first.  I feel like each small part is a hundred sub projects.  It's not nearly complete, but I have a working partial version right now, and I figured I might as well put it out there, see if I get any feedback.  My documentation is pretty sloppy, but I do put effort into documenting it, so you should be able to see what's going on pretty well.  Again, very much a work in progress.  At the moment it's fairly limited in capability, here's some stats:

3 outputs (ULN2003 to 12v relay to 110v relay): a water pump, artificial sunlight and a green LED worklight.  (Green light does not interrupt the darkness requirement flowering photosensitive plants have)

2 analog inputs: temperature sensors, LM34DZ

2 digital inputs : regular momentary NO pushbuttons

http://mulletsoda.seedtheplanet.com/marvin.jpg

http://code.google.com/p/atmega328growcontroller/    <~~ More detailed info

Quote
#include "OutletTimer.h"
#include "DigitalInputter.h"
#include "PrintPJRClcd.h"

/*Initialize outlets, OutletTimer(pinNumber, InitialMode, InitialTimeSec) */
OutletTimer MainLightOutletTimer(10,0,300);// Main light
OutletTimer MainVegPumpOutletTimer(9,1,60);//Water pumps
OutletTimer GreenWorkLightOutletTimer(8,4,0);//work lights

/* Initialize digital inputs DigitalInputter(int pinNumber) */
DigitalInputter WorkLightButton(7);
DigitalInputter PumpToggleButton(6);


/* Open LCD library on serial port */
PrintPJRClcd LCD = PrintPJRClcd(); 

/* Initialize analog inputs */
int AnalogRezTemp = 0;
int AnalogAirTemp = 0;
#define AnalogRezTempPin 0
#define AnalogAirTempPin 1

/* Variables for time watching */
unsigned long previousMillis = 0;        // will store last time millis
unsigned long curMillis = 0;
int timeSinceLast = 0;

/* floats for calculating time */
float MainLightTimeFloat;
unsigned char LoopsAround = 0;
void setup()
{

  /*   Set outlet on and off times  */
  MainLightOutletTimer.OnDuration = 64800; //main lights, 64800 = 18 hours
  MainLightOutletTimer.OffDuration = 21600; // 21600 = 6 hours
  MainVegPumpOutletTimer.OnDuration = 60;//veg pump
  MainVegPumpOutletTimer.OffDuration = 600;
  GreenWorkLightOutletTimer.OnDuration = 0;
  GreenWorkLightOutletTimer.OffDuration = 0;
  Serial.begin(19200);
  delay(1000);
  LCD.RedrawScreen();

}

void loop()
{

  /* Check inputs */
  if (WorkLightButton.CheckPin())   // if work light button has been pushed
  { 
    if (GreenWorkLightOutletTimer.CurrentMode==4) GreenWorkLightOutletTimer.ChangeMode(5); // if current mode is perm off, turn it perm on
    else if (GreenWorkLightOutletTimer.CurrentMode==5) GreenWorkLightOutletTimer.ChangeMode(4);
  };      
  if (PumpToggleButton.CheckPin()) //if pump button has been pushed
  {
    switch(MainVegPumpOutletTimer.CurrentMode) //what's the veg pump at now?
    {
    case 0: //off, normal operation
      MainVegPumpOutletTimer.ChangeMode(1);
      break;
    case 1: //on, normal operation
      MainVegPumpOutletTimer.ChangeMode(4);
      break;
    case 4: // perm off
      MainVegPumpOutletTimer.ChangeMode(5);
      break;
    case 5: // perm on
      MainVegPumpOutletTimer.ChangeMode(0);                  
      break;
    };
  };



  /*measure time past since last loop and increment down */
  curMillis = millis();
  if (curMillis < previousMillis) previousMillis = 0.0; //roll over check
  timeSinceLast = curMillis- previousMillis;
  previousMillis = curMillis;

  /* Analog inputs */
  AnalogRezTemp = analogRead(AnalogRezTempPin);
  AnalogAirTemp = analogRead(AnalogAirTempPin);

  /* Print info to screen */
  //LCD.RedrawScreen();
  LCD.PrintData(0,int(AnalogAirTemp/2.1));
  LCD.PrintData(1,int(AnalogRezTemp/2.1));
  LCD.PrintData(2,MainVegPumpOutletTimer.CurrentMode);
  LCD.PrintData(3,(MainVegPumpOutletTimer.TimeLeft/1000));
  LCD.PrintData(4, MainLightOutletTimer.CurrentMode);
  MainLightTimeFloat = ((long(MainLightOutletTimer.TimeLeft)/1000)/60);
  LCD.PrintData(5, int(MainLightTimeFloat));
  LCD.PrintData(6, GreenWorkLightOutletTimer.CurrentMode);
  /* Pass Time Since Last loop to each outlet */

  MainLightOutletTimer.ElapseTime(timeSinceLast);
  MainVegPumpOutletTimer.ElapseTime(timeSinceLast);
  GreenWorkLightOutletTimer.ElapseTime(timeSinceLast);


  LoopsAround++;
  if(LoopsAround==42) LCD.RedrawScreen();
}


Quote
/*
 *  A library for dealing with digital inputs *  Created by MulletSoda, 2010
 *  With love!
 */

#ifndef DigitalInputter_h
#define DigitalInputter_h

#include "WProgram.h"

class DigitalInputter
{
public:
  //public variables:
  int PinNumber;
  int _PinNumber;
  unsigned long _currentTime;
  unsigned long _deBounceTimeDone;
  boolean _deBounce;
  void DeBouncer();

  //public functions:
  DigitalInputter(int _PinNumber);
  boolean CheckPin();
private:
  //private variables
  //private functions
};

#endif



Quote
#include "WProgram.h"
#include "DigitalInputter.h"


DigitalInputter::DigitalInputter(int PinNumber)
{
  //initialize
  _PinNumber = PinNumber;
  pinMode(_PinNumber, INPUT);
  //digitalWrite(_PinNumber, HIGH);//turn on pull up resistor
  _deBounceTimeDone = 0;
}

boolean DigitalInputter::CheckPin()
{
  _currentTime = millis(); //what is the current time?

  //debounce and check
  if (!_deBounce)  //if deBounce has not been activated
    if (digitalRead(_PinNumber)==1){//read pin, if it returns activated then
      {
        _deBounce = true;
        _deBounceTimeDone =500 + _currentTime; // <*******************************************  Will this bypass the rollover problem????
        //turn on debounce, set time over, return true
        return true;
      };
    };
  if (_deBounce)  //if deBounce has been activated
  {
    if (_deBounceTimeDone <= _currentTime) _deBounce = false; //if enough time has passed
  };
  return false;
}

void DigitalInputter::DeBouncer()
{
}

Pages: [1]