lukelouyu
-
Posts
24 -
Joined
-
Last visited
Content Type
Profiles
Forums
Events
Gallery
Posts posted by lukelouyu
-
-
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:
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.
-
I am currently using DF robot gravity EC sensor and pH sensors
Here are the links for these two sensors:
https://www.dfrobot.com/product-1123.html (EC sensor)
https://www.dfrobot.com/product-1782.html (pH sensor)
Here are design specification:
Thanks
Luke
-
-
Hi, everyone here.
Now, I have tried with my Pmod AD1. I used the demo code provided by the Digilent, but the value shown in the Vitis Serial Terminal is different from the value I have seen in the multimeter.
For example, when I insert my sensor A into the channel A0, the value shown in 2.56. The value shown in the multimeter is 2.9V.
When I insert my sensor B into the channel A1, the value shown in the Vitis Serial Terminal is 1.08. The value shown in the multimeter is about 2.1V.
When the sensor induced voltage exceeds 1.8V, the AD1 value returns back to 0.
I think this diagram might tell me the reason. But I am not sure since I am new to FPGA & electronic and I don't quite understand the datasheet. (Link: https://www.analog.com/media/cn/technical-documentation/evaluation-documentation/AD7476A_7477A_7478A.pdf?_ga=2.196220652.1995249494.1621070558-1887244704.1616928603)
Through comparing with the AD1 reading voltage and the multimeter voltage, i found there is an linear relationship between them. I made an excel file to show you guys the relationship.
I suspected i need to add an additional voltage source but not sure as well. When I connects the Vcc to the D0 or D1, the serial terminal said 3.3V. I did not change anything in the demo code, is there anyway to allow the AD1 reading to be the same as the reading in the multimeter.
Thanks
Luke
[Pmod ESP32] Problem with AT commands: Cannot receive IPD from the Serial Terminal
in FPGA
Posted · Edited by lukelouyu
Add "/r/n" in sprintf((char*)command, "GET https://api.thingspeak.com/channels/"ThingSpeak_Channel_Num"/fields/1.json?results=1" );