Buggfix Plus
Aktuellt datum och tid: 23.20 2018-08-15

Alla tidsangivelser är UTC + 1 timme




Svara på tråd  [ 39 inlägg ]  Gå till sida Föregående  1, 2, 3  Nästa
Författare Meddelande
InläggPostat: 16.14 2015-07-04 

Blev medlem: 18.52 2013-06-03
Inlägg: 163
Tack för svaret. När det regnar nästa gång ska jag göra en testuppkoppling hemma i köket. Sedan gäller det att göra samma sak i båten, måste ha någon bra plats för dispalyen t.ex. Just nu när det är sommarväder är det båt-åka som gäller (utan motorövervakning).


Upp
 Profil  
 
InläggPostat: 19.18 2015-07-13 

Blev medlem: 18.52 2013-06-03
Inlägg: 163
Nu har jag gjort en första testinkoppling. Allt fungerar som det ska, även om displayen har en lite snäv betraktningsvinkel. Lite finjustering av koden och några apparatlådor och kopplingsplintar så är det dags att montera den i båten.
Bilaga:
ImageUploadedByTapatalk1436811496.641037.jpg


Logga in för att visa de filer som bifogats till detta inlägg.


Upp
 Profil  
 
InläggPostat: 19.18 2015-07-15 
Användarvisningsbild

Blev medlem: 21.16 2003-08-15
Inlägg: 2564
Ort: Färingtofta, SKÅNE!
Gott :tumupp:
Funkar det fint med uppdateringsfrekvens osv?


Upp
 Profil  
 
InläggPostat: 17.02 2015-07-18 

Blev medlem: 18.52 2013-06-03
Inlägg: 163
Det funkar fint. Men, när jag kopplade ihop allt med lödningar och skruvplintar i stället för experimentkort fick jag bara konstiga mätvärden (+20 grader blev -125 grader). Dags att labba igen.


Upp
 Profil  
 
InläggPostat: 20.31 2015-07-18 

Blev medlem: 18.52 2013-06-03
Inlägg: 163
Färdiglabbat och fungerar som det ska.
Bilaga:
ImageUploadedByTapatalk1437247857.632497.jpg


Logga in för att visa de filer som bifogats till detta inlägg.


Upp
 Profil  
 
InläggPostat: 20.54 2015-07-18 

Blev medlem: 18.52 2013-06-03
Inlägg: 163
Bilaga:
trim.16B556CB-CB9F-4FF4-9317-D82DDEA6F97E.MOV


Logga in för att visa de filer som bifogats till detta inlägg.


Upp
 Profil  
 
InläggPostat: 10.29 2015-07-20 

Blev medlem: 13.24 2015-07-18
Inlägg: 1
Mycket intressant!!
Då skulle man kunna lägga till en givare för hur mycket motorn är trim/tilt i %
Få nog börja testa lite också :)


Upp
 Profil  
 
InläggPostat: 20.22 2015-08-18 

Blev medlem: 18.52 2013-06-03
Inlägg: 163
Nu är den på plats. Tre temperatursensorer och en hallelementsensor på motorn.
Sensorn för kylvattnet placerades på röret ut från motorn till värmeväxlaren. Sensorn för avgaserna placerades på utsidan av utloppet från limpan. Jag hittade inte någon bra plats att mäta oljetemperaturenmpå så jag fäste den tredje sensorn invid insprutarna på toppen.
Efter en misslyckad montering av magneten på svänghjulet (magneten lossnade av centrifugalkraften och bara försvann), monterade jag en annan magnet tätt intill mittmuttern på svänghjulet där den inte påverkas av så stora krafter.
Sensorkablarna samlas ihop i en låda i motorrummet och en 4-ledare leder signalerna till Arduinon som sitter i en större låda vid styrplatsen. En tredje låda på instrumentpanelen innehåller displayen.
Allt fungerar som det ska förutom att varvtalsvisningen någon gång då och då visar 6000 rpm eller ett stort värde (10 siffror). Jag tror inte det beror på störningar utan något jag missat i koden.
Kan någon av er se varför?


Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
#include <DallasTemperature.h>
#include <OneWire.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

OneWire sensorBus(4); //sensors connected to digital pin 4
DallasTemperature sensors(&sensorBus);

// Connect the LCD with SDA to analog pin 4 and SCL to analog pin 5
// set the LCD address to 0x27 (check the address)
// Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

unsigned long previousMillis = 0;
unsigned long currentMillis = 0;
unsigned long result = 0;

DeviceAddress Oiltemp =
{
  0x28, 0xFF, 0x18, 0x53, 0x02, 0x15, 0x04, 0x67
};
DeviceAddress Watertemp =
{
  0x28, 0xFF, 0x58, 0x54, 0x02, 0x15, 0x04, 0x08
};
DeviceAddress Exhausttemp =
{
  0x28, 0xFF, 0x07, 0x9F, 0x02, 0x15, 0x03, 0xDC
};

int alarm = 7; //the pin number of the alarm 7

void setup()
{
  // Read and display sensor addresses
  delay(1000);
  Serial.begin(9600);
  sensors.begin();

  lcd.begin(16, 2);  // initialize the lcd for 16 chars 2 lines, turn on backlight
  // ------- Quick 3 blinks of backlight  -------------
  for(int i = 0; i < 3; i++)
  {
    lcd.backlight();
    delay(250);
    lcd.noBacklight();
    delay(250);
  }
  lcd.backlight(); // finish with backlight on

  // 3 beeps with alarm
  pinMode(alarm, OUTPUT);
  for(int i = 0; i < 3; i++)
  {
    digitalWrite(alarm, HIGH);
    delay(250);
    digitalWrite(alarm, LOW);
    delay(250);
  }

  // NOTE: Cursor Position: (CHAR, LINE) start at 0
  lcd.setCursor(0, 0); //Start at character 0 on line 0
  lcd.print("Varvtal");  //rad 1
  lcd.setCursor(0, 1);
  lcd.print("Temperatur");  //rad 2
  delay(5000);

  attachInterrupt (0, inputPulse, RISING);  //pulse imput from rev sensor (digital pin 2)

  sensors.setResolution(Oiltemp, 10);
  sensors.setResolution(Watertemp, 10);
  sensors.setResolution(Exhausttemp, 10);

}

void loop()
{
  sensors.requestTemperatures(); // Send the command to get temperatures
 
  Serial.print(sensors.getTempCByIndex(0)); //print temp on screen
  Serial.println(" Degrees C");
  Serial.print(60000 / result); //print rpm on Screen
  Serial.println(" rpm");

  lcd.clear();
  lcd.setCursor(4, 0);
  lcd.print(60000 / result); //print rpm on display
  lcd.print(" rpm  ");

  if (6000 / result > 2500) //alarm on high rpm
  {
    digitalWrite(alarm, HIGH); //alarm signal output
    lcd.setCursor(0, 1);
    lcd.print("WARNING HIGH rpm");
    delay(2000);
  }
  else
    digitalWrite(alarm, LOW);

  sensors.requestTemperatures();
  lcd.setCursor(0, 1); //print temp on display
  lcd.print("Water:   ");
  printTemperature(Watertemp);
  delay (2000);

  lcd.clear();
  lcd.setCursor(4, 0);
  lcd.print(60000 / result); //print rpm on display
  lcd.print(" rpm  ");

  lcd.setCursor(0, 1);
  lcd.print("Oil:     ");
  printTemperature(Oiltemp);
  delay (2000);

  lcd.clear();
  lcd.setCursor(4, 0);
  lcd.print(60000 / result); //print rpm on display
  lcd.print(" rpm  ");

  lcd.setCursor(0, 1);
  lcd.print("Exhaust: ");
  printTemperature(Exhausttemp);
  delay (2000);
}


void printTemperature(DeviceAddress deviceAddress) //read sensors
{

  float tempC = sensors.getTempC(deviceAddress);

  lcd.print(tempC);
  lcd.print(" C ");

  if (tempC > 90.0) //alarm on high temp.
  {
    digitalWrite(alarm, HIGH); //alarm signal output
    lcd.setCursor(0, 0);
    lcd.print(" WARNING TEMP.  ");
    delay(2000);
  }
  else
    digitalWrite(alarm, LOW);

}// End printTemperature


void inputPulse() //interrupt - pulse input digital pin 2
{
  currentMillis = millis();                        //read millis
  result = currentMillis - previousMillis;  //rpm
  previousMillis = currentMillis;                  //prepare for next pulse

}


Logga in för att visa de filer som bifogats till detta inlägg.


Upp
 Profil  
 
InläggPostat: 18.03 2015-08-19 

Blev medlem: 18.52 2013-06-03
Inlägg: 163
Lite ändringar i koden:
Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
#include <DallasTemperature.h>
#include <OneWire.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

OneWire sensorBus(4); //sensors connected to digital pin 4
DallasTemperature sensors(&sensorBus);

// Connect the LCD with SDA to analog pin 4 and SCL to analog pin 5
// set the LCD address to 0x27 (check the address)
// Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

unsigned long previousMillis = 0;
unsigned long currentMillis = 0;
unsigned long result = 0;
unsigned long rpm = 0;

DeviceAddress Oiltemp =
{
   0x28, 0xFF, 0x18, 0x53, 0x02, 0x15, 0x04, 0x67
};
DeviceAddress Watertemp =
{
   0x28, 0xFF, 0x58, 0x54, 0x02, 0x15, 0x04, 0x08
};
DeviceAddress Exhausttemp =
{
   0x28, 0xFF, 0x07, 0x9F, 0x02, 0x15, 0x03, 0xDC
};

int alarm = 7; //the pin number of the alarm

float tempC;

void setup()
{
   // Read and display sensor addresses
   delay(1000);
   Serial.begin(9600);
   sensors.begin();

   lcd.begin(16, 2);  // initialize the lcd for 16 chars 2 lines, turn on backlight
   // ------- Quick 3 blinks of backlight  -------------
   for(int i = 0; i < 3; i++)
   {
      lcd.backlight();
      delay(250);
      lcd.noBacklight();
      delay(250);
   }
   lcd.backlight(); // finish with backlight on

   // 3 beeps with alarm
   pinMode(alarm, OUTPUT);
   for(int i = 0; i < 3; i++)
   {
      digitalWrite(alarm, HIGH);
      delay(250);
      digitalWrite(alarm, LOW);
      delay(250);
   }

   // NOTE: Cursor Position: (CHAR, LINE) start at 0
   lcd.setCursor(0, 0); //Start at character 0 on line 0
   lcd.print("Varvtal");  //rad 1
   lcd.setCursor(0, 1);
   lcd.print("Temperatur");  //rad 2
   delay(5000);

   attachInterrupt (0, inputPulse, RISING);  //pulse imput from rev sensor (digital pin 2)

   sensors.setResolution(Oiltemp, 10);
   sensors.setResolution(Watertemp, 10);
   sensors.setResolution(Exhausttemp, 10);

   lcd.clear();
}

void loop()
{

   sensors.requestTemperatures();
   lcd.setCursor(0, 1); //print temp on display
   lcd.print("Water:   ");
   printTemperature(Watertemp);

   if (tempC > 70) //alarm on high temp.
   {
      digitalWrite(alarm, HIGH); //alarm signal output
      lcd.setCursor(0, 0);
      lcd.print(" WARNING TEMP.  ");
      delay(1000);
   }
   else
      digitalWrite(alarm, LOW);
   

   lcd.setCursor(0, 1);
   lcd.print("Oil:     ");
   printTemperature(Oiltemp);

   if (tempC > 100) //alarm on high temp.
   {
      digitalWrite(alarm, HIGH); //alarm signal output
      lcd.setCursor(0, 0);
      lcd.print(" WARNING TEMP.  ");
      delay(1000);
   }
   else
      digitalWrite(alarm, LOW);

   lcd.setCursor(0, 1);
   lcd.print("Exhaust: ");
   printTemperature(Exhausttemp);

   if (tempC > 70) //alarm on high temp.
   {
      digitalWrite(alarm, HIGH); //alarm signal output
      lcd.setCursor(0, 0);
      lcd.print(" WARNING TEMP.  ");
      delay(1000);
   }
   else
      digitalWrite(alarm, LOW);
}

void printTemperature(DeviceAddress deviceAddress) //read sensors and print result
{
// Read temp
   float tempC = sensors.getTempC(deviceAddress);
// Print temp
   lcd.print(tempC);
   lcd.print(" C ");

// Print RPM
   rpm = 60000 / result;

   if (rpm < 4000) //filter out invalid readings
   {

      lcd.setCursor(4, 0);
      lcd.print(rpm); //print rpm on display
      lcd.print(" rpm  ");

      if (rpm > 2500) //alarm on high rpm
      {
         digitalWrite(alarm, HIGH); //alarm signal output
         lcd.setCursor(0, 1);
         lcd.print("WARNING HIGH rpm");
         delay(1000);
      }
      else
         digitalWrite(alarm, LOW);
      delay(1000);
   }

}// End printTemperature


void inputPulse() //interrupt - pulse input digital pin 2
{
   currentMillis = millis();                        //read millis
   result = currentMillis - previousMillis;  //rpm
   previousMillis = currentMillis;                  //prepare for next pulse
}


Upp
 Profil  
 
InläggPostat: 15.08 2015-08-23 

Blev medlem: 18.52 2013-06-03
Inlägg: 163
Det gick inte alls. Den visar ibland brara två temperaturer och ibland bara en. Dessutom blir det felaktigt övervarvslarm oftare än tidigare. Jag skulle uppskatta ett tips.
Jag får justera koden och försöka igen. Tyvärr kan jag inte ta med datorn till båten, är tvungen att ta hem Arduinon och justera koden och någon dag senare testa.


Upp
 Profil  
 
InläggPostat: 15.58 2015-08-23 
Användarvisningsbild

Blev medlem: 19.48 2013-10-01
Inlägg: 910
Ort: Orust
Är det OK att anropa funktionen millis() från interruptet som du gör?

Edit: Om interruptet inkl. anrop till millis() tar lång kan du få ett nytt interrupt innan du är klar med det första dvs du kanske har ett reentrancy-problem?

Ett alternativ vore annars att bara räkna upp en räknare för antal pulser där. Anrop av millis(), nollställning av räknare och uträkning skulle isf. kunna göras i funktionen loop() med ett visst tidsintervall t.ex var 100:e eller 1000:e ms.

(Anar att denna metod skulle nog behöva någon slags glidande medelvärdesberäkning för att bli stabil, ffa på låga varv.)


Upp
 Profil  
 
InläggPostat: 19.08 2015-08-24 

Blev medlem: 18.52 2013-06-03
Inlägg: 163
Tidsintervallet mellan interrupt är alltid mer än 20 ms. Jag trodde att dessa kommandon skulle hinnas med. Egentligen sparar jag ju bara millis-värdet:

Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)
void inputPulse()
{
   currentMillis = millis();                       
   result = currentMillis - previousMillis; 
   previousMillis = currentMillis;   
}


Jag förstår inte riktigt hur jag ska göra för att få till det du föreslår.


Upp
 Profil  
 
InläggPostat: 19.34 2015-08-24 
Användarvisningsbild

Blev medlem: 19.48 2013-10-01
Inlägg: 910
Ort: Orust
Jag var förmodligen på fel spår men såg kanske en annan sak när jag googlade. Kan det behövas ett 'volatile' i din kod?

Kod: [Expandera/Minimera] [Hämta] (Untitled.txt)

volatile unsigned long result = 0;



https://www.arduino.cc/en/Reference/Volatile


Upp
 Profil  
 
InläggPostat: 19.43 2015-08-26 

Blev medlem: 18.52 2013-06-03
Inlägg: 163
Jag ska ta bort övervarvslarmet och lägga in "volatile". Testar i helgen.
Kanske Metro library eller Timer library skulle vara en annan lösning. Då kan interrupten bara räkna pulser.


Upp
 Profil  
 
InläggPostat: 18.36 2015-08-27 

Blev medlem: 21.19 2009-05-06
Inlägg: 7116
Jag skulle nog deklarerat variablerna globalt (dvs utanför funktionen), då överlever de ju garanterat, fast risken är ju att man råkar använda dem på fel ställe.

Jag har inte orkat kolla på din kod, men jag har som nån labb tidigare skrivit en 'frekvensmätar'-kod som mäter tiden på övre och undre flanken på inkommande signal på en digitalingång, interruptstyrt, och det verkade funka riktigt bra utan "fladder". Jag är rätt säker på att jag använde micros och inte millis. Micros verkar wrappa efter 70 minuter, se till att det blir rätt med aritmetiken både kring detta och signed/unsigned.

P.S. en vanlig funktionsgenerator, gärna med TTL-utgång, är rätt bra att ha för att testa den här typen av grejer. När jag labbade använde jag en funktionsgenerator som dessutom har ställbar asymetri på fyrkantvåg. Jag körde dessutom med en extern frekvensmätare parallellt (fast på "vanliga" utgången) och enligt den så mätte min kod förhållandevis rätt.

För en varvräknare så kan det kanske vara en bra idé att lagra ett antal mätningar i en ringbuffert och visa medelvärde på de senaste mätningarna om de senaste är tillräckligt nära varandra, för att slippa fladder i visningen. När varvtalet ändras snabbare så är det däremot vettigt att visa senaste utan medelvärdesbildning för att få så snabb visning som möjligt, antar jag.


Upp
 Profil  
 
Visa inlägg nyare än:  Sortera efter  
Svara på tråd  [ 39 inlägg ]  Gå till sida Föregående  1, 2, 3  Nästa

Alla tidsangivelser är UTC + 1 timme


Vilka är online

Användare som besöker denna kategori: Bing [Bot] och 2 gäster


Du kan inte skapa nya trådar i denna kategori
Du kan inte svara på trådar i denna kategori
Du kan inte redigera dina inlägg i denna kategori
Du kan inte ta bort dina inlägg i denna kategori
Du kan inte bifoga filer i denna kategori

Sök efter:
Hoppa till:  
   
Drivs av phpBB® Forum Software © phpBB Group
Swedish translation by Peetra & phpBB Sweden © 2006-2010