• 0

Water Pump Control in FPGA through using Timer Interrupt


Question

Posted (edited)

Hi, 

I have been trying to use the zybo board timer interrupt functions to control my water pump while running other program, kind of like multitasking. 

The program goes like this, when the my other programs are running in the while(true) loop (running forever), the water pump will turn on for 12 hours and turn off for 12 hours

Before jumping into actual program, I made some simple testing. While the Pmod HYGRO is getting value, the led 4bits will have a loop of turning on for 100s and turning off 100s (like led toggling) 

Here is what I have tried with built-in led:

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"

#include "xparameters.h";
#include "xgpio.h";
#include "xtmrctr.h";
#include "xscugic.h";
#include "xil_exception.h";

#include "PmodHYGRO.h"
#include "sleep.h"
#include "xil_cache.h"


#ifdef __MICROBLAZE__
#define TIMER_FREQ_HZ XPAR_CPU_M_AXI_DP_FREQ_HZ
#else
#define TIMER_FREQ_HZ 100000000
#endif

PmodHYGRO myDevice;

void DemoInitialize();
void DemoRun();
void DemoCleanup();
void EnableCaches();
void DisableCaches();


// Parameter definitions
#define INTC_DEVICE_ID XPAR_PS7_SCUGIC_0_DEVICE_ID
#define TMR_DEVICE_ID XPAR_TMRCTR_0_DEVICE_ID
#define LEDS_DEVICE_ID XPAR_AXI_GPIO_0_DEVICE_ID
#define INTC_TMR_INTERRUPT_ID XPAR_FABRIC_AXI_TIMER_0_INTERRUPT_INTR

#define TMR_LOAD 0xF8000000


XGpio LEDInst;
XScuGic INTCInst;
XTmrCtr TMRInst;

static int led_data;
static int tmr_count;

//void print (char *str);

static void TMR_Intr_Handler(void *baseaddr_p);
static int IntcInitFunction (u16 DeviceId, XTmrCtr *TmrInstancePtr);

void TMR_Intr_Handler(void *data){
	if (XTmrCtr_IsExpired(&TMRInst,0)){
		// Once timer has expired 3 times, stop, increase counter
		//reset timer and start running again

	if(tmr_count==3){
		XTmrCtr_Stop(&TMRInst,0);
				tmr_count=0;
		//led_data++;
				led_data=~led_data;
		XGpio_DiscreteWrite(&LEDInst,1,led_data);

		XTmrCtr_Reset(&TMRInst,0);
		XTmrCtr_Start(&TMRInst,0);

	}else
		tmr_count++;

	}
}

// Initial Setup Functions

int InterruptSystemSetup(XScuGic *XScuGicInstancePtr){
	// Enable Interrupt

	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
			(Xil_ExceptionHandler) XScuGic_InterruptHandler,
			XScuGicInstancePtr);
	Xil_ExceptionEnable();

	return XST_SUCCESS;

}


int IntcInitFunction (u16 DeviceId, XTmrCtr *TmrInstancePtr){
XScuGic_Config *IntcConfig;
int status;

//Interrupt controller initialisation
IntcConfig=XScuGic_LookupConfig(DeviceId);
status= XScuGic_CfgInitialize(&INTCInst, IntcConfig,
		IntcConfig->CpuBaseAddress);
if (status!= XST_SUCCESS)
	return XST_FAILURE;

//Call to interrupt setup
status= InterruptSystemSetup(&INTCInst);
if (status != XST_SUCCESS)
	return XST_FAILURE;

// Connect timer interrupt to handler
status= XScuGic_Connect(&INTCInst, INTC_TMR_INTERRUPT_ID,
		(Xil_ExceptionHandler) TMR_Intr_Handler, (void*) TmrInstancePtr);
if (status != XST_SUCCESS)
	return XST_FAILURE;

// Enable timer interrupts in the controller
XScuGic_Enable(&INTCInst, INTC_TMR_INTERRUPT_ID);

return XST_SUCCESS;

}



int main()
{
    init_platform();

    led_data=0;
    int status;
    // INITIALISE THE PERIPHERALS & SET DIRECTIONS OF GPIO

    // Initialise LEDs
    status=XGpio_Initialize(&LEDInst, LEDS_DEVICE_ID);
    ;
    if (status != XST_SUCCESS)
    	return XST_FAILURE;

    // Set LEDs direction to outputs
    XGpio_SetDataDirection(&LEDInst, 1,0x00);

    //Initilise interrupt controller
    status=IntcInitFunction(INTC_DEVICE_ID, &TMRInst);
    if (status != XST_SUCCESS)
    	return XST_FAILURE;

    // Set the TIMER
    status= XTmrCtr_Initialize(&TMRInst, TMR_DEVICE_ID);
    	    if (status != XST_SUCCESS)
    	    	return XST_FAILURE;
    XTmrCtr_SetHandler(&TMRInst, (XTmrCtr_Handler) TMR_Intr_Handler, &TMRInst);
    XTmrCtr_SetResetValue(&TMRInst,0,TMR_LOAD);
    XTmrCtr_SetOptions(&TMRInst,0,
    		XTC_INT_MODE_OPTION | XTC_AUTO_RELOAD_OPTION);

   XTmrCtr_Start(&TMRInst,0);


    while(1)
    	 DemoInitialize();
    	   DemoRun();
    	   DemoCleanup();




    return 0;
}

void DemoInitialize() {
   EnableCaches();
   xil_printf("Init Started\n\r");
   HYGRO_begin(
      &myDevice,
      XPAR_PMODHYGRO_0_AXI_LITE_IIC_BASEADDR,
      0x40, // Chip address of PmodHYGRO IIC
      XPAR_PMODHYGRO_0_AXI_LITE_TMR_BASEADDR,
      XPAR_PMODHYGRO_0_DEVICE_ID,
      TIMER_FREQ_HZ // Clock frequency of AXI bus, used to convert timer data
   );
   xil_printf("Init Done\n\r");
}

void DemoCleanup() {
   DisableCaches();
}

void DemoRun() {
   float temp_degc, hum_perrh, temp_degf;
   while (1) {
      temp_degc = HYGRO_getTemperature(&myDevice);
      temp_degf = HYGRO_tempC2F(temp_degc);
      hum_perrh = HYGRO_getHumidity(&myDevice);
      xil_printf(
         "Temperature: %d.%02d deg F  Humidity: %d.%02d RH\n\r",
         (int) temp_degf,
         ((int) (temp_degf * 100)) % 100,
         (int) hum_perrh,
         ((int) (hum_perrh * 100)) % 100
      );
      // %f does not work with xil_printf
      // instead, converting float to a pair of ints to display %.2f.

      // 1 sample per second maximum, as per 9.2.1 in HDC1080 reference manual
      sleep(1);
   }
}

void EnableCaches() {
#ifdef __MICROBLAZE__
#ifdef XPAR_MICROBLAZE_USE_ICACHE
   Xil_ICacheEnable();
#endif
#ifdef XPAR_MICROBLAZE_USE_DCACHE
   Xil_DCacheEnable();
#endif
#endif
}

void DisableCaches() {
#ifdef __MICROBLAZE__
#ifdef XPAR_MICROBLAZE_USE_ICACHE
   Xil_ICacheDisable();
#endif
#ifdef XPAR_MICROBLAZE_USE_DCACHE
   Xil_DCacheDisable();
#endif
#endif
}

Here is Vivado block diagram: 

image.thumb.png.fd670b30361b484478c7852b9f61942a.png

 

Here are some issues faced:

1) when i change value in "if(tmr_count==3)" to a large value, the time of toggling is still within 3s. (if there is no HYGRO code) 

2) the led does not function, but the HYGRO functions when there is code for HYGRO

If anyone can also help me or give me suggestion on water pump timer control, I will be so much appreciate it. I will upload my Vivado block design and Vitis code below for your reference. 

Thanks

Luke Louyu. 

BlockDesignNew.PNG

New Code V1.0.txt

Edited by lukelouyu
Add Block Diagram
Link to post
Share on other sites

0 answers to this question

Recommended Posts

There have been no answers to this question yet

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now