first commit

This commit is contained in:
simon 2020-11-14 13:17:50 +01:00
commit 0be993e537
10 changed files with 640 additions and 0 deletions

BIN
Ansicht-Bot.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

BIN
Ansicht-Top.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

BIN
Bastelplatz.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 573 KiB

Binary file not shown.

View File

@ -0,0 +1,129 @@
:1000000012C02AC029C028C0B7C126C025C041C11E
:1000100023C022C021C020C01FC084C11DC01CC07D
:100020001BC01AC019C011241FBECFEDCDBF10E0F8
:10003000A0E6B0E0E0EFF7E002C005900D92AC362C
:10004000B107D9F720E0ACE6B0E001C01D92AE38B0
:10005000B207E1F72FD2CAC3D3CFCF93DF93FB010F
:10006000E9011A821B821C821D82198218829F83D9
:100070008E83798768875B874A87BC016F5F7F4F74
:100080008FEF9FE7D6D27D876C879F012F5F3F4F11
:10009000442737FD4095542F6FEF7FEF8FEF9FE39D
:1000A000DBD22E873F87488B598BDF91CF91089504
:1000B0008F929F92AF92BF92CF92DF92EF92FF9278
:1000C0000F931F93CF93DF936B017A01E9019C019A
:1000D000261B370B8C859D858217930764F09195BD
:1000E00081959109281739074CF06E817F81C901EC
:1000F0008FD28C0105C00FEF1FE702C001E010E8AE
:10010000442737FD4095542F8A819B81AC81BD8166
:10011000280F391F4A1F5B1F8E859F85A889B989C3
:1001200082179307A407B5075CF48A839B83AC838B
:10013000BD8388248A94982CA82C9FE3B92E26C0CE
:10014000B095A095909581959F4FAF4FBF4F2817C1
:1001500039074A075B075CF48A839B83AC83BD83C2
:1001600088248394912CA12C80ECB82E0FC02A8374
:100170003B834C835D8368857985882777FD8095EF
:10018000982F86D2822E932EA42EB52E8881998107
:100190006A857B858C199D093BD2AC01D982C882C6
:1001A000C801AA2797FDA095BA2F880D991DAA1DF1
:1001B000BB1D662757FD6095762F840F951FA61FE0
:1001C000B71FA701662757FD6095762F840F951FEF
:1001D000A61FB71F813020E892072FEFA207B207B2
:1001E00024F481E090E8AFEFBFEF811520E892079B
:1001F000A105B10524F08FEF9FE7A0E0B0E0DF910B
:10020000CF911F910F91FF90EF90DF90CF90BF9013
:10021000AF909F908F900895F894C498C398FFCFA3
:10022000C198000000000000000000001FB880E43A
:100230008EB98BE18DB9769BFDCF2FB11FB880E4CD
:100240008EB98BE18DB9769BFDCF6FB11FB880E47D
:100250008EB98BE18DB9769BFDCF1FB880E48EB946
:100260008BE18DB9769BFDCFC19A60FDD5DF70E043
:1002700080E090E0722B0895882351F088B3826467
:1002800088BB87B3826C87BB8AE18DB9BD98C59A5C
:1002900008951F920F920FB60F9211242F933F9340
:1002A0004F938F939F934CB180916E0090916F000C
:1002B0005C9B19C0029720F010926B0010926A00AC
:1002C00010926F0010926E0040937A0080917A0035
:1002D000811106C081E080936D0081E090E014C040
:1002E00010926D0015C021E020936D0020916800F0
:1002F000309169008217930711F440937B0082309C
:1003000022E0920728F4019690936F0080936E008C
:100310009F918F914F913F912F910F900FBE0F9012
:100320001F9018951F920F920FB60F9211242F93C2
:100330008F939F9380916C008F5F8F3F19F0809314
:100340006C0002C010926C0080916A0090916B006A
:1003500080349F4148F480916A0090916B0001962F
:1003600090936B0080936A009F918F912F910F90D3
:100370000FBE0F901F9018951F920F920FB60F92FD
:1003800011242F933F934F935F936F937F938F939A
:100390009F93AF93BF93EF93FF9380E690E09BBD55
:1003A0008ABD80917000803589F5809176009091AA
:1003B0007700A0917800B09179008C3C9041A10524
:1003C000B10550F480917100803248F45091710071
:1003D000550F550F40E005C040E050E002C04FEF20
:1003E0005FE760917600709177008091780090913E
:1003F00079002CE730E0809162009091630058DE34
:10040000909373008093720010927000809170003E
:100410008F5F8093700020917000809172009091A6
:100420007300332727FD3095609160007091610063
:1004300000D12617370714F4C49A01C0C49820913C
:10044000700080917100332727FD30958695869541
:1004500090E028173907E4F48091760090917700B6
:10046000A0917800B0917900813A9F40A105B10533
:1004700078F08091760090917700A0917800B0910B
:10048000790084399141A105B10510F4C39A01C0E6
:10049000C398FF91EF91BF91AF919F918F917F9101
:1004A0006F915F914F913F912F910F900FBE0F90E1
:1004B0001F90189512B881E089B98AB180698AB90C
:1004C0001B9A8E98969ABA98C29A8D98959A8C98FB
:1004D000949A8B98939A8A98929A8998919AB898B4
:1004E000C09AB09B06C081E090E090936900809331
:1004F0006800869B0AC080916800909169008058CE
:100500009F4F9093690080936800B29B0AC08091CE
:10051000680090916900805C9F4F90936900809380
:100520006800859B09C08091680090916900809661
:100530009093690080936800849B09C08091680053
:100540009091690040969093690080936800839B26
:1005500009C08091680090916900089690936900A5
:1005600080936800829B09C0809168009091690027
:1005700004969093690080936800819B09C08091E4
:1005800068009091690002969093690080936800DA
:100590004091640050916500609174007091750005
:1005A0002CE730E0809166009091670056DD8DE089
:1005B0008EBD80E690E09BBD8ABD80E489BFBC9A79
:1005C000BB9A81E059DE789480916A0090916B002B
:1005D00080349F4111F410927B0080917B008093C6
:1005E00071001EDE60937600709377008093780030
:1005F000909379008091760090917700A091780097
:10060000B0917900893F9141A105B105E8F204DE7E
:100610000024552704C0080E591F880F991F009702
:1006200029F076956795B8F37105B9F7802D952F68
:10063000089597FB072E16F4009406D077FD08D096
:1006400071D007FC05D03EF4909581959F4F089599
:10065000709561957F4F0895052E97FB16F40094D1
:100660000FD057FD05D072D007FC02D046F408C069
:1006700050954095309521953F4F4F4F5F4F0895CE
:1006800090958095709561957F4F8F4F9F4F0895FE
:1006900068940013E894A0E0B0E0E0E5F3E01DC04A
:1006A000EFEFE7F959016A015E23550FEE08FE2CC2
:1006B00087019B01AC019E23990F660B762FCB011E
:1006C00067D0CDB7DD27EAE01FC02F923F924F924F
:1006D0005F926F927F928F929F92AF92BF92CF92D2
:1006E000DF92EF92FF920F931F93CF93DF93CDB7DB
:1006F000CA1BCDBFDD2709942A88398848885F84C2
:100700006E847D848C849B84AA84B984C884DF80B1
:10071000EE80FD800C811B81AA81D981CE0FCDBFD7
:10072000CA2F0895AA1BBB1B51E107C0AA1FBB1FFC
:10073000A617B70710F0A61BB70B881F991F5A956D
:10074000A9F780959095BC01CD010895A1E21A2EDC
:10075000AA1BBB1BFD010DC0AA1FBB1FEE1FFF1F65
:10076000A217B307E407F50720F0A21BB30BE40BB5
:10077000F50B661F771F881F991F1A9469F76095FC
:100780007095809590959B01AC01BD01CF010895B6
:10079000DF93CF939F92A0E49A2E0024D001E00132
:1007A000F00116950795F794E794D794C794B794FA
:1007B000A79448F41068A20FB31FC41FD51FE61FEB
:1007C000F71F081E191E220F331F441F551F661FD7
:1007D000771F881F991F9A9421F79D01AE01BF01D1
:1007E000C00111249F90CF91DF910895F894FFCF1D
:0C07F00099017C10280055000100401FFA
:00000001FF

124
Firmware/pid.c Normal file
View File

@ -0,0 +1,124 @@
/*This file has been prepared for Doxygen automatic documentation generation.*/
#include "pid.h"
#include "stdint.h"
void pid_Init(int16_t p_factor, int16_t i_factor, int16_t d_factor, struct PID_DATA *pid)
// Set up PID controller parameters
{
// Start values for PID controller
pid->sumError = 0;
pid->lastProcessValue = 0;
// Tuning constants for PID loop
pid->P_Factor = p_factor;
pid->I_Factor = i_factor;
pid->D_Factor = d_factor;
// Limits to avoid overflow
pid->maxError = MAX_INT / (pid->P_Factor + 1);
pid->maxSumError = MAX_I_TERM / (pid->I_Factor + 1);
}
/*
int16_t pid_Controller(int16_t setPoint, int16_t processValue, struct PID_DATA *pid_st)
{
int16_t error, p_term, d_term;
int32_t i_term, ret, temp;
error = setPoint - processValue;
// Calculate Pterm and limit error overflow
if (error > pid_st->maxError){
p_term = MAX_INT;
}
else if (error < -pid_st->maxError){
p_term = -MAX_INT;
}
else{
p_term = pid_st->P_Factor * error;
}
// Calculate Iterm and limit integral runaway
temp = pid_st->sumError + error;
if(temp > pid_st->maxSumError){
i_term = MAX_I_TERM;
pid_st->sumError = pid_st->maxSumError;
}
else if(temp < -pid_st->maxSumError){
i_term = -MAX_I_TERM;
pid_st->sumError = -pid_st->maxSumError;
}
else{
pid_st->sumError = temp;
i_term = pid_st->I_Factor * pid_st->sumError;
}
// Calculate Dterm
d_term = pid_st->D_Factor * (pid_st->lastProcessValue - processValue);
pid_st->lastProcessValue = processValue;
ret = (p_term + i_term + d_term) / SCALING_FACTOR;
if(ret > MAX_INT){
ret = MAX_INT;
}
else if(ret < -MAX_INT){
ret = -MAX_INT;
}
return((int16_t)ret);
} */
int16_t pid_Controller(int16_t setPoint, int16_t processValue, int16_t errorValue, struct PID_DATA *pid_st)
{
int16_t error, p_term, d_term;
int32_t i_term, ret, temp;
error = setPoint - processValue;
// Calculate Pterm and limit error overflow
if (error > pid_st->maxError){
p_term = MAX_INT;
}
else if (error < -pid_st->maxError){
p_term = -MAX_INT;
}
else{
p_term = pid_st->P_Factor * error;
}
// Calculate Iterm and limit integral runaway
temp = pid_st->sumError + error;
if(temp > pid_st->maxSumError){
i_term = MAX_I_TERM;
pid_st->sumError = pid_st->maxSumError;
}
else if(temp < -pid_st->maxSumError){
i_term = -MAX_I_TERM;
pid_st->sumError = -pid_st->maxSumError;
}
else{
pid_st->sumError = temp;
i_term = pid_st->I_Factor * pid_st->sumError;
}
// Calculate Dterm
d_term = pid_st->D_Factor * (pid_st->lastProcessValue - processValue);
pid_st->lastProcessValue = processValue;
//ret = (p_term + i_term + d_term + errorValue) / SCALING_FACTOR;
ret = (p_term + i_term + d_term + errorValue) / SCALING_FACTOR;
if(ret > (int32_t) MAX_INT){
ret = MAX_INT;
}
else if(ret < (int32_t) -MAX_INT){
ret = -MAX_INT;
}
return((int16_t)ret);
}
void pid_Reset_Integrator(pidData_t *pid_st)
{
pid_st->sumError = 0;
}

34
Firmware/pid.h Normal file
View File

@ -0,0 +1,34 @@
/*This file has been prepared for Doxygen automatic documentation generation.*/
#ifndef PID_H
#define PID_H
#include "stdint.h"
#define SCALING_FACTOR 1
typedef struct PID_DATA{
int16_t lastProcessValue;
int32_t sumError;
int16_t P_Factor;
int16_t I_Factor;
int16_t D_Factor;
int16_t maxError;
int32_t maxSumError;
} pidData_t;
// Maximum value of variables
#define MAX_INT INT16_MAX
#define MAX_LONG INT32_MAX
#define MAX_I_TERM (MAX_LONG / 2)
// Boolean values
#define FALSE 0
#define TRUE 1
void pid_Init(int16_t p_factor, int16_t i_factor, int16_t d_factor, struct PID_DATA *pid);
//int16_t pid_Controller(int16_t setPoint, int16_t processValue, struct PID_DATA *pid_st);
int16_t pid_Controller(int16_t setPoint, int16_t processValue, int16_t errorValue, struct PID_DATA *pid_st);
void pid_Reset_Integrator(pidData_t *pid_st);
#endif

311
Firmware/test3_tiny2313.c Normal file
View File

@ -0,0 +1,311 @@
//https://homepages.uni-regensburg.de/~erc24492/PID-Regler/AVR221/IAR/doxygen/main_8c-source.html
#include <avr/interrupt.h>
#include <avr/io.h>
#include <stdio.h>
#include "pid.h"
#define F_CPU 8000000UL
#define BAUD 250000UL
#define F_TIMER 80L // Timer1 ISR-Frequenz != 1Hz
#define T1_PRESCALER 1024 // Hardware-Vorteiler für Timer 1,
// muss mit der Konfiguratiom übereinstimmen!
#define OCRx_RELOAD ((F_CPU / (T1_PRESCALER * F_TIMER)) -1) // Periodendauer pro Interrupt
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
#error
#endif
#define HEATER_PIN_OUT DDRB |= (1<<PB4);
#define PUMP_PIN_OUT DDRB |= (1<<PB3);
#define HEATER_ON PORTB |= (1<<PB4);
#define HEATER_OFF PORTB &= ~(1<<PB4);
#define PUMP_ON PORTB |= (1<<PB3);
#define PUMP_OFF PORTB &= ~(1<<PB3);
//MISO = PB6 DO
//MOSI = PB5 DI
//CS = PB1
//SCK = PB7
#define CS_DIS PORTB |= (1<<PB1);
#define CS_EN PORTB &= ~(1<<PB1);
#define DMX_BAUD 250000
#define DMX_LOST_TIMEOUT 8000
volatile unsigned int dmx_lost = DMX_LOST_TIMEOUT;
volatile unsigned int dmx_adresse = 1;
volatile unsigned char dmx_buffer[2];
//volatile unsigned char led_kanal[3];
volatile unsigned long temperature;
//4500 ca 285°C //OFF
//4400 ca 278°C
//4300 ca 272°C
//4250 ca 270°C
//4200 ca 262°C
// ca 250°C //ON
//3800 ca 238°C
//3500 ca 220°C
//3200 ca 200°C
//2800 ca 175°C
//2500 ca 156°C
//2200 ca 138°C
//1800 ca 115°C
//1400 ca 100°C
//1200 ca 80°C
//570 ca 50°C
//340 ca 25°C
//KR bei 125V = 520 -> 130 bei 230V
//P_C ca 90s
//PWM bei 3670 (275°C)
//heizen 32000 bei DMX-Wert= 32
struct PID_DATA pidData;
int16_t p_factor = 85; //85
int16_t i_factor = 0; //1
int16_t d_factor = 40; //11
int16_t processValue = 1024; //Ist-Temp
int16_t setPoint = 4220; //Soll-Temp (275°C) 4220
int16_t Factor = (32767/80);
volatile int16_t PWM = 0; //16Bit PWM
volatile uint8_t PUMP = 0; //8Bit PWM
volatile int8_t T = 0;
void Fehler() {
cli(); //Interrupts aus
HEATER_OFF; //Heizung aus
PUMP_OFF; //Pumpe aus
while (1) {
//Hält Maschine bei Fehler an
}
}
long spi()
{
//Max31855 einlesen
unsigned char y = 0;
unsigned char x = 0;
long wert;
CS_EN; //Enable CS
for(unsigned long tmpa = 0;tmpa<5;tmpa++)asm("nop"); //ca 100ns warten
//Byte 1
USIDR = 0x0;
USISR = (1<<USIOIF);
do {
USICR = (1<<USIWM0)|(1<<USICS1)|(1<<USICLK)|(1<<USITC);
} while ((USISR & (1<<USIOIF)) == 0);
x = (unsigned int)USIDR;
// Byte2
USIDR = 0x0;
USISR = (1<<USIOIF);
do {
USICR = (1<<USIWM0)|(1<<USICS1)|(1<<USICLK)|(1<<USITC);
} while ((USISR & (1<<USIOIF)) == 0);
y = (unsigned int)USIDR;
// Byte 3
USIDR = 0x0;
USISR = (1<<USIOIF);
do {
USICR = (1<<USIWM0)|(1<<USICS1)|(1<<USICLK)|(1<<USITC);
} while ((USISR & (1<<USIOIF)) == 0);
//Byte 4
USIDR = 0x0;
USISR = (1<<USIOIF);
do {
USICR = (1<<USIWM0)|(1<<USICS1)|(1<<USICLK)|(1<<USITC);
} while ((USISR & (1<<USIOIF)) == 0);
CS_DIS; //Disable CS
//Prüfen ob Sensor angeschlossen ist
if (y & 0x01) {Fehler();}
wert = (unsigned long) (((long)x << 8) | (long)y);
return wert;
}
void enable_spi(unsigned char speed)
{
if (speed) {
PORTB |= (1<<PB6)|(1<<PB1); // pull-up i.e. disabled
DDRB |= (1<<PB7)|(1<<PB6)|(1<<PB1);
USICR = (1<<USIWM0)|(1<<USICS1)|(1<<USICLK);
DDRB &= ~(1<<PB5); //Input: PB6=DI (MOSI)
PORTB |= (1<<PB5); //interner Pull-up an PA6 aktivieren
};
}
//DMX Empfangen
ISR (USART_RX_vect)
{
static unsigned int dmx_channel_rx_count = 0;
static unsigned char dmx_valid = 0;
unsigned char recv = 0;
recv = UDR;
if(UCSRA&(1<<FE))
{
if(dmx_channel_rx_count > 1)
{
dmx_lost = 0;
}
dmx_channel_rx_count = 0;
dmx_buffer[0] = recv;
if(dmx_buffer[0] == 0)
{
dmx_valid = 1;
dmx_channel_rx_count++;
}
else
{
dmx_valid = 0;
}
return;
}
//Test da DMX einen Fehler geworfen hat
dmx_valid = 1;
if(dmx_valid)
{
//PUMP_ON;
if(dmx_channel_rx_count == dmx_adresse) dmx_buffer[1] = recv;
if(dmx_channel_rx_count < 514)
{
dmx_channel_rx_count++;
}
//PUMP_OFF;
return;
}
}
ISR (TIMER0_COMPA_vect)
{
static unsigned char pwm_counter = 0;
pwm_counter++;
if(pwm_counter == 255)
{
pwm_counter = 0;
}
if(dmx_lost<DMX_LOST_TIMEOUT)
{
dmx_lost++;
}
}
ISR (TIMER1_COMPA_vect) {
OCR1A = OCRx_RELOAD; //Timer neu laden
if (T == 80) {
int16_t z;
//Störgrößenaufschaltung bei niedriger Temperatur
if (temperature < 4300) {
if (PUMP < 32) {z = PUMP * 1024;} else {z = 32767;}; //Pumpenleistung bestimmen
} else {z = 0;}; //Bei kleinerer temperatur wird Störgröße aufgeschaltet //32 entspricht 32000 sollleistung
PWM = pid_Controller(setPoint, temperature, z, &pidData); //SetPoint = tsoll, processValue = tist errorValue = Pumpenleistung
T=0;
}
T++; //PWM mit 80 schritten
//Heizung schalten
if (T < (PWM / Factor)) {HEATER_ON;} else {HEATER_OFF;};
//Pumpe mit PWM einschalten, falls temperatur > 250° und kleiner 300°C
if (T < (PUMP / 4) && (temperature > 4000) && (temperature < 4500)) {PUMP_ON;} else {PUMP_OFF;};
}
//Hauptprogramm
int main (void)
{
//Init usart
UBRRH = UBRR_VAL >> 8;
UBRRL = UBRR_VAL & 0xFF;
UCSRB|=(1 << RXEN | 1<< RXCIE);
UCSRC|=(1<<USBS);
//Inputs setzen
DDRD &= ~(1 << PD6); // switch input pin
PORTD |= (1 << PD6); // enable pull-up resistor
DDRB &= ~(1 << PB2); // switch input pin
PORTB |= (1 << PB2); // enable pull-up resistor
DDRD &= ~(1 << PD5); // switch input pin
PORTD |= (1 << PD5); // enable pull-up resistor
DDRD &= ~(1 << PD4); // switch input pin
PORTD |= (1 << PD4); // enable pull-up resistor
DDRD &= ~(1 << PD3); // switch input pin
PORTD |= (1 << PD3); // enable pull-up resistor
DDRD &= ~(1 << PD2); // switch input pin
PORTD |= (1 << PD2); // enable pull-up resistor
DDRD &= ~(1 << PD1); // switch input pin
PORTD |= (1 << PD1); // enable pull-up resistor
DDRB &= ~(1 << PB0); // switch input pin
PORTB |= (1 << PB0); // enable pull-up resistor
//DMX-Adresse einlesen;
// dmx_adresse = 0;
if (PINB & (1 << PB0)) dmx_adresse =1;
if (PIND & (1 << PD6)) dmx_adresse +=128;
if (PINB & (1 << PB2)) dmx_adresse +=64;
if (PIND & (1 << PD5)) dmx_adresse +=32;
if (PIND & (1 << PD4)) dmx_adresse +=16;
if (PIND & (1 << PD3)) dmx_adresse +=8;
if (PIND & (1 << PD2)) dmx_adresse +=4;
if (PIND & (1 << PD1)) dmx_adresse +=2;
//PID Konfigurieren:
pid_Init(p_factor, i_factor , d_factor , &pidData);
// Timer 1 freigeben
TCCR1B = (1<<WGM12)| (1<<CS12) | (1<<CS10); //Vorteiler 1024
OCR1A = OCRx_RELOAD;
// OCR1A Interrupt freigeben, wird für Timer CTC mode benutzt
TIMSK = 1<<OCIE1A;
// DDRD |=(1<<PD2);
// PORTD &=~(1<<PD2);
HEATER_PIN_OUT;
PUMP_PIN_OUT;
enable_spi(1);
sei();
while(1)
{
if(dmx_lost==DMX_LOST_TIMEOUT)
{
dmx_buffer[1] = 0;
};
PUMP = dmx_buffer[1];
temperature = spi();
if (temperature > 4600) Fehler();
}
}

BIN
Nebelmaschine-V1_2.pdf Normal file

Binary file not shown.

42
README.md Normal file
View File

@ -0,0 +1,42 @@
![Nebelmaschine]
# DMX-Nebelmaschine
Für die kleinen Nebelmaschinen zum umbauen.
###Vorteile:
- Bessere Temperaturregelung mit PD-Regler
- Dauernebeln mit niedriger Stufe möglich (f ca 1Hz)
- DMX-Steuerung
- Keine langen Pausen mehr zum Nachheitzen
Firmware schreiben mit:
avrdude -c jtag3isp -p attiny2313 -U flash:w:test3_tiny2313.hex
###Achtung:
Nebel wird bei zu hohen temperaturen toxisch
Elektrischer Schlag möglich bei unsachgemäßer Verwendung
Brandgefahr
-> nur für fortgeschrittene Bastler und erfahrene Profis
![Bastelplatz]
Thermoelement (Typ-K) mit Schraubanschluss verwenden damit dieser sich nicht löst und den Thermoschalter im Heitzkreis belassen. Dieser Schaltet bei Übertemperatur die Heitzung aus. Am Netzspannungseingang ist eine passende Sicherung zu verwenden.
##Patches auf der Platine (V1.1):
![Top]
![Bot]
[Nebelmaschine]: pic1.jpg "Fertige Nebelmaschine"
[Bastelplatz]: Bastelplatz.jpg "Nebelmaschine bei debuggen"
[Top]: Ansicht-top.jpg "Platine Top"
[Bot]: Ansicht-bot.jpg "Platine Bot"