Akvariekontroller

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Arclight
Inlägg: 77
Blev medlem: 31 oktober 2013, 09:49:10

Akvariekontroller

Inlägg av Arclight »

EDIT.. Jag ändra rubrik då det är med än servofunktionen jag skulle behöva lite hjälp med.

Först, tack för alla svar, kommer att kolla över dom alternativen så fort jag är klar med de grundläggande funktionerna.
Just nu tragglar jag som fasen med dels att visa de båda ledens dimmerstatus i procent som ska skrivas ut på displayen, hur fasen gör man det? testade något där jag gjorde en read på pin11 och fick ut ett resultat på displayen men den visade ju helt knas.. just nu har jag bara lagt in så den visar minuter bara för att få ett dynamiskt värde så jag kan lägga övriga tecken på rätt ställe. Hoppas jag lyckades förklara på någorlunda vettigt sätt:)

Det andra (som egentligen inte är superviktigt, men bara jäkligt störigt) är att temperaturvärdet som visas har två decimaler, dvs den visar ex 25.75 och jag vill den bara ska visa 25.7. finns det nåt bra sätt att fixa detta på?

Håller på med en ver 2 av min akvariumkontroller och ska implementera bla en fiskmatare, denna bygger på ett microservo och den ska göra en enkel -180 och tillbaka till 180 vid ett visst klockslag. jag tycker ju det låter som en skitenkel grej, men det visade sig att så var ju inte fallet.

Jag får den till att gå fram och tillbaka vid given tid men inte hela vägen (180 -180), och under övrig tid så är den lite orolig och man känner i den att den liksom rycker lite så det känns som det inte stämmer riktigt, har letat som fasen efter lösningar men kan inte hitta några, skulle även vilja få in den kod jag har där jag ställer hur fort den ska röra sig (//for (pos = 0; pos <= 180; pos += 2) {) men hur jag än försöker så får jag felmeddelanden på den.

Så om någon vänlig själ har lust att kolla på det skulle jag (och mitt humör) vara väldigt tacksam:)

Här är (den uppdaterade) koden jag har.

Kod: Markera allt

#define _Digole_Serial_UART_
#include <DigoleSerial.h>
#include "Wire.h"
#include "Servo.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#define DS1307_ADDRESS 0x68
#define ONE_WIRE_BUS 2
#define COOLFAN  10
#define BLUELED  5
#define WHITELED  11
OneWire oneWire(ONE_WIRE_BUS);
DigoleSerialDisp mydisp(&Serial, 9600);
DallasTemperature sensors(&oneWire);
DeviceAddress tempProbe = { 0x28, 0xFF, 0xFF, 0x3A, 0x10, 0x14, 0x00, 0x4F };
Servo Feeder;
int pos = -180;
float tempC;
int M100 = 0;
int relay_out = 0;
int relay;

void setup(void)
{
  Wire.begin();
  Serial.begin(9600);
  sensors.begin();
  Feeder.attach(3);
  sensors.setResolution(tempProbe, 10);
  pinMode(COOLFAN, OUTPUT);
  pinMode(BLUELED, OUTPUT);
  pinMode(WHITELED, OUTPUT);
  mydisp.begin();
  mydisp.clearScreen();
}

void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  if (tempC == -127.00) {
    mydisp.disableCursor();
    mydisp.setPrintPos(11, 0);
    mydisp.setFont(100);
    mydisp.print("ERROR");
  } else {
    mydisp.setPrintPos(9, 0);
    mydisp.setFont(100);
    mydisp.print("C:");
    mydisp.setPrintPos(11, 0);
    mydisp.setFont(100);
    mydisp.print(tempC);
  }
}

void loop(void)
{
  printDate();
  delay(1000);
}

byte bcdToDec(byte val)  {
  return ( (val / 16 * 10) + (val % 16) );
}

void printDate() {

  Wire.beginTransmission(DS1307_ADDRESS);

  byte zero = 0x00;
  Wire.write(zero);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_ADDRESS, 7);

  int second = bcdToDec(Wire.read());
  int minute = bcdToDec(Wire.read());
  int hour = bcdToDec(Wire.read() & 0b111111);
  int weekDay = bcdToDec(Wire.read());
  int monthDay = bcdToDec(Wire.read());
  int month = bcdToDec(Wire.read());
  int year = bcdToDec(Wire.read());

  mydisp.setPrintPos(0, 0);
  mydisp.setFont(100);
  mydisp.print("T:");
  if (hour < 10)
  {
    mydisp.print("0");
  }
  mydisp.print(hour);
  mydisp.print(":");
  if (minute < 10)
  {
    mydisp.print("0");
  }
  mydisp.print(minute);
  mydisp.setPrintPos(0, 1);
  mydisp.print("WHITE LED:");
  mydisp.setPrintPos(0, 2);
  mydisp.print("BLUE LED:");
  mydisp.setPrintPos(0, 3);
  mydisp.print("COOLER FAN:");
  mydisp.setPrintPos(0, 4);
  mydisp.print("FEEDER T:  18:00");
  sensors.requestTemperatures();
  printTemperature(tempProbe);

//FEEDER FUNCTION

  if ((hour == 18 ) && ( minute == 00 ) && ( second <= 2 ))
    Feeder.write(180);
  delay(400);
  Feeder.write(-180);

  //for (pos = 0; pos <= 180; pos += 2) {
  //for (pos = 180; pos >= 0; pos -= 2) {

//TEMPERATURE RELAY FUNCTION

  tempC = sensors.getTempC(tempProbe);

  if (tempC > 26.50) {
    M100 = 1;
    relay_out = 0;
  }
  if (tempC <= 26) {
    M100 = 0;
    relay_out = 1;
  }
  if ((tempC >= 26) && (tempC <= 26.50) && (M100 = 0)) {
    relay_out = 1;
  }
  relay = relay_out;
  if (relay == 1) {
    analogWrite (COOLFAN, 0);
    mydisp.setPrintPos(12, 3);
    mydisp.print("IDLE");
  }
  else {
    analogWrite (COOLFAN, 255);
    mydisp.setPrintPos(12, 3);
    mydisp.print("100%");
  }

//LED DIMMER FUNCTION
//WHITELED
  //LED FADE IN
  if (hour == 13) {
    analogWrite (WHITELED, map(minute, 0, 59, 0, 255) );
    mydisp.setPrintPos(12, 1);
            if (minute < 10)
  {
    mydisp.print("  ");
  }
              if (minute > 10)
  {
    mydisp.print(" ");
  }
    mydisp.print((minute));
    mydisp.print("%");
  }
  //LED ON
  else if ((hour >= 14 ) and (hour < 22 )) {
    analogWrite (WHITELED, 255);
    mydisp.setPrintPos(12, 1);
    mydisp.print("100%");
  }
  //LED FADE OUT
  else if (hour == 22 ) {
    analogWrite (WHITELED, map(minute, 0, 59, 255, 0) );
    mydisp.setPrintPos(13, 1);
            if (minute < 10)
  {
    mydisp.print("  ");
  }
    mydisp.print((minute));
    mydisp.print("%");
  }
  //LED OFF
  else {
    analogWrite (WHITELED, 0);
    mydisp.setPrintPos(12, 1);
    mydisp.print("  0%");
  }
//BLUELED
  if (hour == 12) {
    analogWrite (BLUELED, map(minute, 0, 59, 0, 255) );
    mydisp.setPrintPos(13, 2);
            if (minute < 10)
  {
    mydisp.print("  ");
  }
    mydisp.print((minute));
    mydisp.print("%");
  }
  //LED ON
  else if ((hour >= 13 ) and (hour < 23 )) {
    analogWrite (BLUELED, 255);
    mydisp.setPrintPos(12, 2);
    mydisp.print("100%");
  }
  //LED FADE OUT
  else if (hour == 23 ) {
    analogWrite (BLUELED, map(minute, 0, 59, 255, 0) );
    mydisp.setPrintPos(12, 2);
        if (minute < 10)
  {
    mydisp.print("  ");
  }
          if (minute > 10)
  {
    mydisp.print(" ");
  }
    mydisp.print((minute));
    mydisp.print("%");
  }
  //LED OFF
  else {
    analogWrite (BLUELED, 0);
    mydisp.setPrintPos(12, 2);
    mydisp.print("  0%");
  }
}
Senast redigerad av Arclight 18 september 2015, 00:09:40, redigerad totalt 1 gång.
Användarvisningsbild
Xyzzy
Inlägg: 1260
Blev medlem: 30 januari 2004, 22:31:07
Ort: Uppsala, Sweden

Re: Tidsstyra servo..

Inlägg av Xyzzy »

De flesta servos för radiostyrt klarar inte så stort utslag, men det finns undantag.
Hur är specen på din?
Arclight
Inlägg: 77
Blev medlem: 31 oktober 2013, 09:49:10

Re: Tidsstyra servo..

Inlägg av Arclight »

Jo det är lugnt, den klarar det, har fått den till att göra med med annan kod när jag testade den först, det är en micro servo SG90, men det kan förmodligen bara ha med timing och delay att göra, men att den står och "rycker" upprepat precis som att den antingen vill köra åt riktningen den redan står åt max eller nåt känns inte rätt, verkar som att den gör det oftast var 10 sek och förmodligen är det inom området (<2second) men den gör det även lite oregelbundet. känns bara som att koden inte är helt rätt iaf.
kodar-holger
EF Sponsor
Inlägg: 970
Blev medlem: 26 maj 2014, 12:54:35
Ort: Karlskoga

Re: Tidsstyra servo..

Inlägg av kodar-holger »

Har du läst dokumentationen för servobiblioteket? Nedanstående text fanns hos pjrc där jag brukar läsa saker eftersom jag kör enbart teensy 3.1
myservo.write(angle);

Move the servo motor to a new angle, between 0 to 180 degrees. Some servo motors are not capable of a full 180 degree travel or have stability problems at the far ends of this range.
Hur vill du att den långsamma matningen skall bete sig? Berätta med ord. Hur lång tid vridning skall ta et.c.

Just nu ser det ut som om din funktion printDate sköter allt och den anropas ungefär en gång per sekund. Eftersom det sitter delay inuti den funktionen också så blir det lite variabelt. Jag tycker du skall spana in ett bibliotek som heter metro som är till för att schemalägga saker.

Jag tror inte du kommer att kunna använda for för att åstadkomma din långsamma servo-vridning.
hummel
Inlägg: 2543
Blev medlem: 28 november 2009, 10:40:52
Ort: Stockholm

Re: Tidsstyra servo..

Inlägg av hummel »

Servot verkar inte klara 360° utan endast 180°, vilket i sig är mycket redan det.
Alex_Holo
Inlägg: 69
Blev medlem: 21 november 2010, 18:40:50

Re: Tidsstyra servo..

Inlägg av Alex_Holo »

Håller just nu på med ett projekt där ett par servon ska göra något liknande. Använde while istället för for då detta funkade bättre, av någon anledning.
delay är inte alltid bästa lösningen, men i mitt fall ska det inte hända något annat samtidigt som servot gör sitt slag, så detta blev enklast för att styra hastigheten.

Kod: Markera allt

while(Servo_One_Pos > Servo_One_Pos_Front){
  Servo_One.write(Servo_One_Pos);
  Servo_One_Pos = Servo_One_Pos - Servo_Slow_Step;
  delay(Servo_Slow_Delay);
}
Hade även problem med "störningar" och att servona rycker. Kollegan hade upplevt samma problem och sa att det var bl.a delay som ställer till det. PWM signalen fick fel pulslängd.
Ingen aning om det är orsaken, men lösningen blev att köra via I2C istället med separat drivare. Funkar klockrent :D
https://www.adafruit.com/products/815
kodar-holger
EF Sponsor
Inlägg: 970
Blev medlem: 26 maj 2014, 12:54:35
Ort: Karlskoga

Re: Tidsstyra servo..

Inlägg av kodar-holger »

Mer klipp från dokumentation på nätet.
Servo uses precisely timed interrupts to generate the control signals to many servo motors. Normally you do not need to be concerned about these interrupts. However, if your program disables interrupts, or you use a library which disables interrupts for substantial periods of time, Servo's signal accuracy can be degraded. Typical problems involve servo motors making small, unintended movements at infrequent, seemingly random times.
X-IL
EF Sponsor
Inlägg: 8484
Blev medlem: 3 december 2008, 07:47:20
Ort: Hallstahammar

Re: Tidsstyra servo..

Inlägg av X-IL »

Det du får köra med din "slow-move" är väl att räkna upp till tänkt utslag i inkrement om ett visst antal grader, och sen köra en delay. Typ så här:

Kod: Markera allt


for (pos = 0; pos <= 180; ) 
{
    Feeder.write(pos);
    delay(waitTime);
    pos = pos+2;
}



Går givetvis att skriva om till en while eller med adderingen i for-satsen osv.
Skriv svar