- AMD GPU-k jövője - amit tudni vélünk
- Milyen belső merevlemezt vegyek?
- NVIDIA GeForce RTX 5080 / 5090 (GB203 / 202)
- TCL LCD és LED TV-k
- Apple MacBook
- AMD Navi Radeon™ RX 9xxx sorozat
- Sugárhajtómű ihlette a Zalman CPU-hűtőjét, de nem az üzemzaj tekintetében
- AMD Ryzen 9 / 7 / 5 9***(X) "Zen 5" (AM5)
- Bluetooth hangszórók
- Milyen TV-t vegyek?
Új hozzászólás Aktív témák
-
Itt egy kód. Nem a végleges, mert azt most valamiért nem találom (asszem notin fejeztem be, az meg most nincs velem), de a lényeg megvan itt is.
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>
#include <Metro.h>
#include <PID_v1.h>
#include <PID_AutoTune_v0.h>
#define ONE_WIRE_BUS_PIN 0
#define TIME_INTERVAL 100
#define INITIAL_INTERVAL 800
#define REPEAT_INTERVAL 100
Metro keyboardTimer(100); // keyboard timer intervals
Metro cookingTimer(1000); // confirm timer
Metro powerTimer(100);
OneWire oneWire(ONE_WIRE_BUS_PIN);
DallasTemperature sensors(&oneWire);
DeviceAddress Probe01 = { 0x28, 0x2C, 0xBA, 0xE6, 0x03, 0x00, 0x00, 0x83 };
DeviceAddress Probe02 = { 0x28, 0xEA, 0xD8, 0xE6, 0x03, 0x00, 0x00, 0x3C };
DeviceAddress Probe03 = { 0x28, 0xE6, 0xD7, 0xE6, 0x03, 0x00, 0x00, 0x2E };
DeviceAddress Probe04 = { 0x28, 0xEB, 0xBD, 0xE6, 0x03, 0x00, 0x00, 0xC8 };
LiquidCrystal lcd(8, 9, 10, 11, 12, 13); // setup LCD
#define keyboardAnalogInput 0 // keyboard analog pin
// #define MAX_STRING_LEN = 32;
// #define MAX_WORDS = 10;
// lang definitions
const char* TEXT_WELCOME_L1 = "Sous Viduino";
const char* TEXT_WELCOME_L2 = "Udvozollek!";
const char* TEXT_TEMP_LONG = "Homerseklet";
const char* TEXT_TEMP = "H";
const char* TEXT_DEG = "C";
const char* TEXT_TIME_LONG = "Fozesi ido";
const char* TEXT_TIME = "I";
const char* TEXT_MINUTE = "perc";
const char* TEXT_CURRENT_TEMP_L1 = "Pillanatnyi";
const char* TEXT_CURRENT_TEMP_L2 = "homerseklet";
const char* TEXT_TIME_REMAINING = "Hatralevo ido";
const char* TEXT_ARE_YOU_SURE = "Egeszen biztos?";
const char* TEXT_YES = "IGEN";
const char* TEXT_NO = "NEM";
const char* TEXT_BACK = "Vissza";
const char* TEXT_START_COOKING = "Fozes inditasa";
const char* TEXT_PREHEATING = "Elomelegites";
const char* TEXT_COOKING = "Fozes";
const char* TEXT_TURN_OFF = "Kikapcsolas";
const char* TEXT_BYE_L1 = "Sous Viduino";
const char* TEXT_BYE_L2 = "Viszlat!";
const char* TEXT_ERROR = "Hijnye, baj van.";
const char* TEXT_SENSOR_FAIL = "Homero hiba.";
// keyboard button definitions
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnENTER 4
#define confNONE 5
#define confNO 0
#define confYES 1
int keyIn = 0; // keyboard analog value
int buttonPressed; // keyboard digital value
int i = 0;
int prevButton = confNONE; // stores previous digital value
int counter = 0; // for keyoard repeats
int Temp = 50;
int Time = 240;
int menuItem = 1;
int menuSize = 3;
int confValue = confNO;
int Confirm = 0;
int Cooking = 0;
int Error = 0;
int tempError = 0;
const char* Status = TEXT_PREHEATING;
float temp1;
float temp2;
float temp3;
float temp4;
float tempAvg;
unsigned int timeRemaining = 0;
int tempSetting = 0;
//////////////////////
byte ATuneModeRemember = 2;
double input = 40, output = 1000, setpoint = 30;
double kp = 1000, ki = 0.0, kd = 0.0;
double kpmodel = 1.5, taup = 100, theta[50];
double outputStart = 5;
double aTuneStep = 50, aTuneNoise = 1, aTuneStartValue = 400;
unsigned int aTuneLookBack = 20;
boolean tuning = false;
unsigned long modelTime, serialTime;
PID myPID(&input, &output, &setpoint, kp, ki, kd, DIRECT);
PID_ATune aTune(&input, &output);
//set to false to connect to the real world
boolean useSimulation = false;
///////////////////////
void setup()
{
sensors.begin();
sensors.setResolution(Probe01, 12);
sensors.setResolution(Probe02, 12);
sensors.setResolution(Probe03, 12);
sensors.setResolution(Probe04, 12);
delay(500);
lcd.begin(16, 2); // init LCD
lcd.print(TEXT_WELCOME_L1);
lcd.setCursor(0, 1);
lcd.print(TEXT_WELCOME_L2);
delay(3000);
lcd.clear();
lcd.print(TEXT_TEMP_LONG);
lcd.setCursor(0, 1);
lcd.print("50 C");
////////////////////////
myPID.SetOutputLimits(0, 1000);
if(useSimulation) {
for(byte i = 0; i < 50; i++) {
theta[i] = outputStart;
}
modelTime = 0;
}
//Setup the pid
myPID.SetMode(AUTOMATIC);
if(tuning) {
tuning = false;
changeAutoTune();
tuning = true;
}
//////////////////////
}
void loop()
{
if (keyboardTimer.check() == 1 && !Error) {
lcd.setCursor(0, 1);
buttonPressed = readKeyboard(); // read digital value
if (buttonPressed == confNONE) counter = 0; // if button released, reset counter
if (prevButton == buttonPressed) { // if button kept pressed
++counter;
if (counter < (INITIAL_INTERVAL / TIME_INTERVAL) || counter % (REPEAT_INTERVAL / TIME_INTERVAL)) buttonPressed = confNONE; // if repeat timer not active, drop keyboard value
} else if (buttonPressed == confNONE) prevButton = buttonPressed;
if (buttonPressed != confNONE) // if new key or repeat active
{
switch(buttonPressed) {
int result;
case btnUP:
if(menuItem > 3) break; // draw only for main menu
menuItem = (menuItem == 1) ? menuSize : menuItem - 1; // move in the main menu
showMenu(menuItem);
break;
case btnDOWN:
if(menuItem > 3) break; // draw only for main menu
menuItem = (menuItem == menuSize) ? 1 : menuItem + 1; // move in main menu
showMenu(menuItem);
break;
case btnRIGHT:
switch(menuItem) {
case 1:
showValue(++Temp, TEXT_DEG); // increase temp
break;
case 2:
if(Time < 999) showValue(++Time, TEXT_MINUTE); // increase time
break;
case 4:
showConfirm(confValue = ((confValue == confYES) ? confNO : confYES)); // select reply
break;
}
break;
case btnLEFT:
if (menuItem == 1 && Temp > 0) showValue(--Temp, TEXT_DEG); // decrease temp, stay above zero
if (menuItem == 2 && Time > 0) showValue(--Time, TEXT_MINUTE); // decrease time, stay above zero
if (menuItem == 4) showConfirm(confValue = ((confValue == confYES) ? confNO : confYES)); // select reply
break;
case btnENTER:
switch(menuItem) {
case 3: // show confirm menu
Confirm = 1;
confValue = confNO;
showConfirm(confValue);
menuItem = 4;
break;
case 4:
Confirm = 0;
if(confValue == confYES) { // start cooking
Cooking = 1;
menuItem = 5;
timeRemaining = Time * 60;
tempSetting = Temp;
setpoint = tempSetting;
lcd.clear();
}
else {
menuItem = 1; // return to main menu
showMenu(menuItem);
}
}
break;
}
prevButton = buttonPressed; // store
}
}
if (cookingTimer.check() == 1 && Cooking && !Error) {
// showStatus(Status);
if (Status == TEXT_COOKING) timeRemaining--;
sensors.requestTemperatures();
temp1 = sensors.getTempC(Probe01);
temp2 = sensors.getTempC(Probe02);
temp3 = sensors.getTempC(Probe03);
temp4 = sensors.getTempC(Probe04);
if (temp1 > 0 && temp1 < 110 && temp2 > 0 && temp2 < 110 && temp3 > 0 && temp3 < 110 && temp4 > 0 && temp4 < 110) {
tempError = 0;
tempAvg = (temp1 + temp2 + temp3 + temp4) / 4;
/* lcd.setCursor(0, 1);
lcd.print(TEXT_TEMP);
lcd.print(":");
lcd.print(tempAvg);
lcd.print(" ");
lcd.setCursor(8, 1);
lcd.print(TEXT_TIME);
lcd.print(":");
lcd.print(timeRemaining / 60);
lcd.print(":");
if (timeRemaining % 60 < 10) lcd.print("0");
lcd.print(timeRemaining % 60); */
/////////////////////////
if(!useSimulation) input = tempAvg;
if(tuning) {
byte val = (aTune.Runtime());
if (val != 0) {
tuning = false;
}
if(!tuning) { //we're done, set the tuning parameters
kp = aTune.GetKp();
ki = aTune.GetKi();
kd = aTune.GetKd();
myPID.SetTunings(kp, ki, kd);
AutoTuneHelper(false);
}
}
else myPID.Compute();
if(useSimulation) {
theta[30] = output;
DoModel();
}
//// else analogWrite(0,output);
//send-receive with processing if it's time
SerialSend();
//////////////////
} else {
if (++tempError > 10) {
lcd.clear();
lcd.print(TEXT_ERROR);
lcd.setCursor(0, 1);
lcd.print(TEXT_SENSOR_FAIL);
Error = 1;
}
}
}
}
int showStatus(const char* currStatus) {
lcd.setCursor(0, 0);
lcd.print(currStatus);
}
int readKeyboard()
{
keyIn = analogRead(keyboardAnalogInput);
// read the value from the sensor
// buttons when read are centered at these values: 0, 144, 329, 504, 741
// add approx 70 to those values and check to see if we are close
if (keyIn > 1000) return confNONE;
if (keyIn < 70) return btnLEFT;
if (keyIn < 215) return btnUP;
if (keyIn < 400) return btnDOWN;
if (keyIn < 575) return btnRIGHT;
if (keyIn < 810) return btnENTER;
return confNONE; // when all others fail, return this...
}
void showValue(int Value, const char* Unit) {
lcd.setCursor(0, 1);
lcd.print(Value);
lcd.print(" ");
lcd.print(Unit);
lcd.print(" "); // to clear
}
void showMenu(int Menu) {
lcd.clear();
switch(Menu) {
case 1:
lcd.print(TEXT_TEMP_LONG); // temp
showValue(Temp, TEXT_DEG);
break;
case 2:
lcd.print(TEXT_TIME_LONG); // time
showValue(Time, TEXT_MINUTE);
break;
case 3:
lcd.print(TEXT_START_COOKING);
break;
// default:
// lcd.print(TEXT_ERROR);
}
}
void showConfirm(int Value)
{
if (Confirm == 1) {
lcd.clear(); // reset screen for first use only
lcd.print(TEXT_ARE_YOU_SURE);
Confirm++;
}
lcd.setCursor(0, 1); // draw selection
if (Value == confYES) lcd.print("#"); else lcd.print(" ");
lcd.print(TEXT_YES);
if (Value == confYES) lcd.print("#"); else lcd.print(" ");
if (Value == confNO) lcd.print("#"); else lcd.print(" ");;
lcd.print(TEXT_NO);
if (Value == confNO) lcd.print("#"); else lcd.print(" ");;
}
void printTemperature(DeviceAddress deviceAddress, byte pos)
{
float tempC = sensors.getTempC(deviceAddress);
switch(pos) {
case 1:
lcd.setCursor(0, 0);
break;
case 2:
lcd.setCursor(8, 0);
break;
case 3:
lcd.setCursor(0, 1);
break;
case 4:
lcd.setCursor(8, 1);
break;
}
if (tempC == -127.00) lcd.print("Error"); else lcd.print(tempC);
}
/////////////////////////////
void changeAutoTune()
{
if(!tuning)
{
//Set the output to the desired starting frequency.
output = aTuneStartValue;
aTune.SetNoiseBand(aTuneNoise);
aTune.SetOutputStep(aTuneStep);
aTune.SetLookbackSec((int)aTuneLookBack);
AutoTuneHelper(true);
tuning = true;
}
else
{ //cancel autotune
aTune.Cancel();
tuning = false;
AutoTuneHelper(false);
}
}
void AutoTuneHelper(boolean start)
{
if(start)
ATuneModeRemember = myPID.GetMode();
else
myPID.SetMode(ATuneModeRemember);
}
void SerialSend()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("i"); lcd.print(input); lcd.print(" ");
lcd.print("o"); lcd.print(output); // lcd.print(" ");
lcd.setCursor(0, 1);
// if(tuning){
// lcd.print("tuning mode");
// } else {
lcd.print("p"); lcd.print(myPID.GetKp()); // lcd.print(" ");
lcd.print("i"); lcd.print(myPID.GetKi()); // lcd.print(" ");
lcd.print("d"); lcd.print(myPID.GetKd());
// }
}
void DoModel()
{
//cycle the dead time
for(byte i=0;i<49;i++)
{
theta[i] = theta[i+1];
}
//compute the input
input = (kpmodel / taup) *(theta[0]-outputStart) + input*(1-1/taup) + ((float)random(-10,10))/100;
} -
Legyen valamilyen öntanuló elektronikája, a relé kimenő teljesítménye elegendő legyen (ezzel nem lesz gond), és az elektronika tényleg tudja, amit ráírtak (ez valószínű)
Továbbá szüksége lesz egy vízmozgatóra is (keverő vagy szivattyú), különben nagyon egyenetlen lesz a vízhőmérséklet. Az én itteni példámból hiányzik a vízmozgató, de van 4 hőmérő és 2 forraló. Viszont ez így ebben a formában működésképtelen volt. Amikor viszont belekerült a vízmozgató, utána elég volt egy forraló és egy hőmérő (van az említett csomagban).
-
-
válasz
sing1ep1ayer #11 üzenetére
A kész étel fagyasztás nélkül hetekig eláll a hűtőben, tehát bármikor előre elkészítheted. Tálalás előtt csak át kell sütni egy pillanatra, hogy sültes kérge keletkezzen. Tehát az ebéd elkészítése a fogyasztás előtt csak pár percet vesz igénybe, ennél gyorsabban nem lehet ételt készíteni. A bonyolultabb ételek így készülnek a jobb éttermekben, ellenkező esetben szegény vendégnek órákat kellene várnia.
A fűtőszállal nem lesz gond, nem megy az folyamatosan, a PWM vezérléssel kábé 5-10%-on fűt, hogy tartsa a hőmérsékletet.
-
Az alapmenüt megszakításokkal fogom vezérelni, egy megszakításrutinban a delay pedig maga a halál
(#3) lapa
1. Minden húsfajtának megvan a maga receptje (hőmérséklet, idő). Ha az összes mérési ponton eléri a kívánt hőmérsékletet a víz, akkor indul a főzési idő.2. Igen, a főzési időre van hatással. De az állaga is más egy kuktás ételnek, mint egy nem kuktásnak. Ugyanígy különbözik állagában a 100 fokon és az 50-70 fokon készített étel. Ezen kívül az étel nem érintkezik sem vízzel, sem oxigénnel.
3. Valóban nincs effektív vákuum. Azért kell vákuumfóliázni, mert így a zacskóban nincs jelen hőszigetelő levegőbuborék, ami miatt nem lenne garantálható a maghőmérséklet, továbbá se a főzés során, sem pedig a későbbi tárolás során nincs jelen levegő, így az étel nem oxidálódik, jobb az íz, és tovább eltartható.
Ez első rész, a cikk következő részében lesznek képek, Arduino kód, videó.
(#4) hcl
Az ábrák painttel készültek(#5) sonar
Olyan nincs, hogy valami nem sörnyitó
Új hozzászólás Aktív témák
Hirdetés
- LG 27GS60QC-B - 27" Ívelt - 2560x1440 - 180Hz 1ms - AMD FreeSync - Bontatlan - 2 Év Gyári Garancia
- AKCIÓ! ASRock H310CM i3 9100F 8GB DDR4 240GB SSD 1TB HDD GTX 1060 3GB AeroCool Strike-X 500W
- Bomba ár! Dell Latitude E6510 - i5-560M I 4GB I 250GB I DVD I 15,6" HD+ I Garancia!
- Apple iPhone 14 128Gb Kártyafüggetlen, 1Év Garanciával
- ÁRGARANCIA!Épített KomPhone Ryzen 7 5700X 16/32/64GB RAM RX 7600 8GB GAMER PC termékbeszámítással
Állásajánlatok
Cég: CAMERA-PRO Hungary Kft
Város: Budapest
Cég: PCMENTOR SZERVIZ KFT.
Város: Budapest