/* modbus slave PA 3cm control rgk aug 2021 bedoeld voor arduino rgk_board (met Atmega32 !!!!!!!!!!!!!) versie 3.0 10 aug 2021 */ #include #include /* SimpleModbusSlaveV10 supports function 3, 6 & 16. The modbus_update() method updates the holdingRegs register array and checks communication. REG_1 = control register (read) REG_2 = status register (write) */ #define MCP 0x4d //I2c adres van de MCP9800 temperatuursensor #define SLAVE_ID 4 // modbus slave adres #define TX_RX 10 // RS485 Rx/Tx omschakel lijn // digital pins #define NET_230 23 //PC7 #define WG_SW 22 //PC6 #define LV_SUP 21 //PC5 #define BLOWER 20 //PC4 #define LOF_1 19 //PC3 #define LOF_0 18 //PC2 #define PWR_CTRL 15 //PD7 Pas Op afwijkend van oude schema ,die gebruikte PB3 maar dat kan niet meer vanwege timer1 gebruik #define bl_rpm 14 //PD6 = ICP pin #define bias 0 #define wg 1 #define tmp 2 #define blower 3 #define att_level 4 #define att_out A6 #define wg_chk A7 #define bias_chk A1 #define att_in A2 static volatile unsigned int Previous_Caption; static volatile unsigned int Sync_Period = 0; // getal = aantal cpu clocken static volatile unsigned char roll_over; static volatile unsigned char capt; //analog inputs Er zit een onverklaarbare verspringing in de anaoge inputs> A0=A2 A1=A3 enz A6=A0 en A7=A1 //byte att_out = A6; //PA0 //byte wg_chk = A7; //PA1 //byte bias_chk = A1; //PA3 //byte att_in = A2; //PA4 unsigned long tijd; unsigned long tijd_oud=0; int interval=200; ISR(TIMER1_OVF_vect) { roll_over++; if (roll_over > 2) { roll_over = 2; capt = 0; } } ISR(TIMER1_CAPT_vect) { if (ICR1 > Previous_Caption) Sync_Period = ICR1 - Previous_Caption; else Sync_Period = (0x10000 - Previous_Caption) + ICR1; roll_over = 0; capt++; if(capt >10) capt = 10; Previous_Caption = ICR1; } // Using the enum instruction allows for an easy method for adding and // removing registers. Doing it this way saves you #defining the size // of your slaves register array each time you want to add more registers // and at a glimpse informs you of your slaves register layout. //////////////// registers of your slave /////////////////// enum { // just add or remove registers and your good to go... // The first register starts at address 0 CTRL, RPM, TEMP, ATT, HOLDING_REGS_SIZE // leave this one // total number of registers for function 3 and 16 share the same register array // i.e. the same address space }; unsigned int holdingRegs[HOLDING_REGS_SIZE]; // function 3 and 16 register array //////////////////////////////////////////////////////////// void setup() { analogReference(INTERNAL);// referentie spanning 2.56V Wire.begin(); // start de i2c service modbus_configure(&Serial, 38400, SERIAL_8N2, SLAVE_ID, TX_RX, HOLDING_REGS_SIZE, holdingRegs); pinMode(TX_RX,OUTPUT); pinMode(bl_rpm,INPUT);// Input Capture unit for measuring the period time of the sync pulse pinMode(NET_230,OUTPUT); pinMode(WG_SW,OUTPUT); pinMode(LV_SUP,OUTPUT); pinMode(BLOWER,OUTPUT); pinMode(LOF_0,OUTPUT); pinMode(LOF_1,OUTPUT); pinMode(PWR_CTRL,OUTPUT); // timer 2 prescaler op 1x en fast pwm zetten voor hogere pwm frequentie TCCR2 = 0x69; analogWrite(PWR_CTRL,0x01); // Timer(s)/Counter(s) Interrupt(s) initialization TCCR1A = 0; TCCR1B = 0; TCCR1B = (1 << ICES1) | (1 << CS11); // Prescale -> :8 TIFR |= (1< interval) { state++; tijd_oud = tijd; } DIGITAL = lowByte(holdingRegs[CTRL]);// lsb is stuurregister voor relais en overige controlpins if(DIGITAL!=DIGITAL_OLD){ lof_0 = bitRead(DIGITAL,0); lof_1 = bitRead(DIGITAL,1); tx_stb = bitRead(DIGITAL,5); digitalWrite(LOF_0,lof_0); digitalWrite(LOF_1,lof_1); digitalWrite(LV_SUP,tx_stb); DIGITAL_OLD=DIGITAL; } pwm=highByte(holdingRegs[CTRL]);//msb is stuurregister voor de power regeling(pwm sturing) analogWrite(PWR_CTRL,pwm); holdingRegs[RPM]=freq*30; holdingRegs[ATT]=analogRead(att_in);// analoge ingang hangt aan de richtkoppelaar //condities checken voor het inschakelen van de hoofdvoeding // blower speed error = 0; bool blw = true; if(capt<10) { blw = false; freq = 0; } if(roll_over < 2) { freq = 2000000/Sync_Period; if((freq < 100 | freq > 170)) { blw = false; } } else blw = false; if(blw==false) bitSet(error,blower); else bitClear(error,blower); int bias_read; int wg_read; int att_read; bias_read = analogRead(bias_chk); wg_read = analogRead(wg_chk); att_read = analogRead(att_out); if(bias_read > min_bias_voltage) bitSet(error,bias); else bitClear(error,bias); if(wg_read < min_wg_current) bitSet(error,wg); else bitClear(error,wg); temp = get_temp(); if(temp > 50) bitSet(error,tmp); else bitClear(error,tmp); if(att_read < 3) bitSet(error, att_level); else bitClear(error,att_level); // send error status in lowbyte en temperatuur in highbyte van het temp register error &= 0x1F; holdingRegs[TEMP]=0; holdingRegs[TEMP]=(temp<<8); holdingRegs[TEMP] += error; tx_on = bitRead(DIGITAL,7); digitalWrite(BLOWER,tx_on); digitalWrite(WG_SW,tx_on); fatal = error & 0x0F;// att_level hier niet als fatale error meenemen //state teller tbv aanlopen blower en WG_Switch if(tx_on){ if(state > 10 && fatal == 0) net = true; else net = false; if(state > 11)state = 11; } else{net = false; state=0; } digitalWrite(NET_230,net);// nu wordt er pas echt ingeschakeld! }//einde hoofdloop char get_temp(){ Wire.beginTransmission(MCP); Wire.write(00); Wire.requestFrom(MCP,2); char hi = Wire.read(); char lo = Wire.read();//wordt verder niks mee gedaan if(hi>127)hi-=256; //02-complements correctie return hi; }