Code Examples Forum Discussions
Hi,
こんにちは、
This morning, I wrote a simple uart sample without using interrupt for CY8CKIT-059 in the discussion below.
今朝、下記のスレッドで CY8CKIT-059 用に割込みを使わない簡単な UART のサンプルを書いてみました。
Re: UART Mapping with SWD/JTAG in CY8CKIT-059 PSoC® 5LP Prototyping Kit
Somehow, I liked the code as a sample, I also ported it to CY8CKIT-044.
そのコードがなんとなく気に入ったので、CY8CKIT-044 にも移植してみました。
As this sample is not using a user-level interrupt for UART, it would be easier to read.
But I wold think that for a real applications, using an interrupt will be better.
このサンプルは割込みを使用していないので、読みやすいと思います。
しかし、本格的なアプリケーションではやはり割込みを使用した方が良いとも思います。
When you compile and run the program, it will look like the picture below.
Only when you type "on", the Green LED on the board lights.
A the string entered will be displayed so that you can be sure that the program is receiving the input.
プログラムをコンパイルして実行すると、下記の様になります。
入力に on と打ち込んだ時だけ、基板上の緑色LEDが点灯します。
そして入力された文字列も表示されますので、ちゃんとプログラムが文字列を受け取っていることが確認できます。
schematic / 回路図
pin / ピンアサイン
main.c
==========================
#include "project.h"
#include "stdio.h"
#define STR_LEN 32
#define BS '\b'
#define CR '\r'
#define NL '\n'
#define LED_ON 0u
#define LED_OFF 1u
void print(char *str)
{
UART_UartPutString(str) ;
}
void printc(char c)
{
UART_UartPutChar(c) ;
}
int main(void)
{
int str_received = 0 ;
uint8_t c ;
char str[STR_LEN+1] ; /* 1 for NULL */
int index = 0 ;
CyGlobalIntEnable; /* Enable global interrupts. */
LED_Write(LED_OFF) ;
UART_Start() ;
print("\x1b[2J\x1b[;H") ; /* clear screen */
print("A Simple UART Test on CY8CKIT-044 ") ;
snprintf(str, STR_LEN, "(%s %s)\n\r", __DATE__, __TIME__) ;
print(str) ;
print("> ") ;
for(;;)
{
if ((str_received == 0)&&(UART_SpiUartGetRxBufferSize() > 0)) { /* received some lstters */
c = UART_UartGetByte() ;
switch(c) {
case BS: /* backspace */
if (index > 0) {
index-- ;
str[index] = 0 ;
print("\b \b") ; /* BS, space, BS */
}
break ;
case CR:
case NL:
str[index] = 0 ; /* terminate the string */
index = 0 ;
str_received = 1 ;
printc(c) ;
break ;
default:
str[index] = c ;
index++ ;
if (index >= STR_LEN) { /* buffer overflow */
str[STR_LEN] = 0 ;
index = 0 ;
str_received = -1 ;
}
printc(c) ;
break ;
}
}
if (str_received) { /* a string is received (or overflow) */
if (strcmp(str, "on") == 0) {
LED_Write(LED_ON) ;
} else {
LED_Write(LED_OFF) ;
}
print("String Received: ") ;
print(str) ;
print("\n\r") ;
str_received = 0 ;
print("> ") ;
}
}
}
/* [] END OF FILE */
==========================
moto
Show LessHi all,
The electronic dice I posted last time was very popular. Many people have requested that we make on PSoC 4 version, so I made it based on CY8CKIT-044. I have also created a new LED lighting board. This time it is based on Arduino. Before introducing the actual electronic dice program, I will first introduce the program for hardware confirmation. If you make a mistake, it will be difficult to debug, so please use this LED test program as one of the electronic dice courses. Here I make a roulette to check the lighting of each LED.
The environment used is as follows:
・PSoC Creator 4.3
・CY8CKIT-044
The block diagram of the hardware is the same as the 7 eyes dice. In the case of dice, the decoding part is changed and timer control is performed by S/W. This time it's an LED test, so it's for confirming that all the LEDs are lit properly.
The H/W block diagram is shown below. I will explain in order from the right of the block. The LED part is the Arduino custom board.
The LED parts are connected to the Arduino connector on the kit. The circuit of the connector and LED used is shown below.
By using the demux component for the counter value, the decoder section can shift the blinking of the LED by one each time it counts up. Since the LED lights up at Low, the output is inverted.
The counter uses the Basic Counter component and the Digital comparator component in combination. Resetting the counter with a count of 5 represents a Modulo 6 counter.
The whole circuit is as follows.
The timer for period adjustment is PWM. Use HFClk divided by 10 KHz as the clock source. The setting of PWM_1 is as follows.
The program is only the start setting of PWM_1.
#include "project.h"
int main(void)
{
CyGlobalIntEnable; /* Enable global interrupts. */
/* Place your initialization/startup code here (e.g. MyInst_Start()) */
PWM_1_Start();
for(;;)
{
/* Place your application code here. */
}
}
/* [] END OF FILE */
Run and check everything when the LEDs light up like a roulette wheel shift. If it does not blink or if the operation is strange, check the H/W of your custom board.
Thanks,
Kenshow
Show LessHi.
This sample uses CY8CKIT-059.
This sample code is based on “https://www.cypress.com/documentation/application-notes/an57473-usb-hid-basics-psoc-3-and-psoc-5lp”.
This "AN57473" has 5 buttons, but add 1 button to make 6 buttons.
I hope this sample will help you evaluate USB HID.
schematics
Pin list
USBFS component
AN57473 This sample
Usage Maximum (5) ⇒ Usage Maximum (6)
Report Count (5) ⇒ Report Count (6)
Report Size (3) ⇒ Report Size (2)
main.c
===========================================
void ReadButtons (void)
{
if(Thumb_Button_Read() != 0) /* Detect if button was pressed */
Buttons |= 0x01; /* If pressed, mask bit to indicate button press */
else
Buttons &= ~0x01; /* If released, clear bit */
if(Button_A_Read() != 0)
Buttons |= 0x02;
else
Buttons &= ~0x02;
if(Button_B_Read() != 0)
Buttons |= 0x04;
else
Buttons &= ~0x04;
if(Button_C_Read() != 0)
Buttons |= 0x08;
else
Buttons &= ~0x08;
if(Button_D_Read() != 0)
Buttons |= 0x10;
else
Buttons &= ~0x10;
if(Button_E_Read() != 0)
Buttons |= 0x20;
else
Buttons &= ~0x20;
}
===========================================
Breadboard wiring diagram
Game controller property
Thanks,
Asanuma
Show Less
Hello,
Download Bootloadable by I2C communication.
Please refer to AN86526 for usage.
https://japan.cypress.com/documentation/application-notes/an86526-psoc-4-i2c-bootloader
condition: I2C CLK:400kHz, I2C slave address:0x08
The downloaded Bootloadable communicates with I2C.
See below for usage.
I2C slave with 2slave address for CY8CKIT145-40XX
condition: I2C CLK:100kHz, I2C slave address:0x0a
Best regards,
Yocchi
Show LessHi all,
I created a new Arduino board for lighting LEDs on PSoC 4, so I also deployed it on PSOC6. I had a counter available in PSoC 4, but I didn't find a similar component in PSoC 6. Instead, there was a down counter, so I changed to a circuit design using that.
The environment used is as follows:
・PSoC Creator 4.2
・CY8CKIT-062-BLE
The components are placed on the PSoC 6 kit so that sound and CapSense can be used. The decoding circuit has also been simplified. The circuit of PSoC6 is as follows.
The pin assignments are as follows.
The program on CM4 is as follows:
//#define SW2 // If you want to use sw2 instad of Capsense, uncomment this line.
#include "project.h"
uint32_t sw=0; //sw is off (Stop rolling dicce)
int main(void)
{
__enable_irq(); /* Enable global interrupts. */
/* Place your initialization/startup code here (e.g. MyInst_Start()) */
Clock_Enable() ;
#ifndef SW2
CapSense_Start();
CapSense_ScanAllWidgets(); // Start Initial Scan
#endif
Count7_1_Start();
for(;;)
{
#ifdef SW2
if(sw==0){
if(Cy_GPIO_Read(SW2_0_PORT,SW2_NUM)==0){
Timer_SetPeriod(400);
Timer_SetCounter(0);
Timer_Start(); // Start rolling dice
sw=1;
}
}
if(sw==1){
if(Cy_GPIO_Read(SW2_0_PORT,SW2_NUM)==1){
/* Roll dice slowly */
Timer_SetPeriod(2000);
Timer_SetCounter(0);
CyDelay(1500); // keep rolling slowly for 1.5sec
Timer_Disable();// Stop rolling dice
sw=0; // sw is off
}
}
#else
if(!CapSense_IsBusy())
{
CapSense_ProcessAllWidgets();
if(sw==0){ // If sw is on, check start botton0.
if(CapSense_IsWidgetActive(CapSense_BUTTON0_WDGT_ID)) // Check button 0 state
{
/* Start rolling dice*/
PWM_1_SetCounter(0);
PWM_1_SetPeriod0(399);
//PWM_1_SetCompare0(200);
PWM_1_Start(); // Start rolling dice
PWM_2_Start();
sw=1; // sw is on
}
}
if(sw==1){ // If sw is on, check stop botton0.
if(CapSense_IsWidgetActive(CapSense_BUTTON1_WDGT_ID)) // Check button 1 state
{
/* Roll dice slowly */
PWM_1_SetCounter(0);
PWM_1_SetPeriod0(1999);
//PWM_1_SetCompare0(200);
CyDelay(1500); // keep rolling slowly for 1.5sec
PWM_1_Disable();// Stop rolling dice
PWM_2_Disable();
sw=0; // sw is off
}
}
CapSense_UpdateAllBaselines();
CapSense_ScanAllWidgets(); // Start next scan
}
#endif
}
}
/* [] END OF FILE */
Reference information
- Concept of electronic dice: Let's make the dice of seven eyes with PSoC 6 (M4), the protagonist of the game
Thanks,
Kenshow
Show LessHi,
I wanted to evaluate the self buttons on CY8CKIT-149 for PSoC4100S Plus. Since the three buttons are assigned to CSX(mutual-cap) in CE220891, I reassigned them to CSD(self-cap). If you want to make the same evaluation, please refer to this sample program. The sliders and their associated LEDs are disabled and deleted in TopDesign.cysch, DesignWideResource and main.c. The parameters of CapSense are configured roughly by manual tuning.
Best regards,
Show LessHi all,
The electronic dice I posted last time was very popular. Many people have requested that we make on PSoC 4 version, so I made it based on CY8CKIT-044. See previous post for more details on the design of the "PSoC 4 Seven Eyes Dice" and “PSoC 4 Seven Eyes Dice with sound”. Here, I will describe using a proximity sensor instead of a switch.
The environment used is as follows:
・PSoC Creator 4.3
・CY8CKIT-044
CapSence for proximity sensor is added to the previous circuit. The circuit of PSoC4 is as follows.
The pin assignments are as follows.
The settings of the CapSense component used in CE of CY8CKIT_044_CapSense_Proximity are used as they are.
The settings are as follows.
The program adds CapSense Proximity instead of SW2.
#include "project.h"
/*****************************************************************************
* MACRO Definition
*****************************************************************************/
#define FALSE 0x00
#define TRUE 0x01
/* 4 ILO periods expressed in microseconds. */
#define ILOX4 ((4 * 1000) / 32)
#define INACTIVE 0
#define ACTIVE 1
#define RESET 0
/* MAX_VALUE defined to achieve 3 second duration.
* See the explanation for variable softCounter in main.c. */
#define MAX_VALUE 100
#define ZERO 0x00
#define OFF 0x00
#define ON 0x01
#define PROX_UPPER_LIMIT 55000
#define PROX_LOWER_LIMIT CapSense_SensorBaseline[0]
uint32_t sw=0; //sw is off (Stop rolling dicce)
int main(void)
{
/* Proximity sensor state. */
uint8 proximity = INACTIVE;
CyGlobalIntEnable; /* Enable global interrupts. */
/* Enable and start the CapSense block. */
CapSense_Start();
/* Initialize the baselines of all CapSense widgets. */
CapSense_InitializeSensorBaseline(CapSense_PROXIMITYSENSOR__PROX);
/* Enable and start PWM block. */
PWM_2_Start();
for(;;)
{
/* Update the baseline of the proximity sensor. */
CapSense_UpdateSensorBaseline(CapSense_PROXIMITYSENSOR__PROX);
/* Scan the proximity sensor. */
CapSense_ScanSensor(CapSense_PROXIMITYSENSOR__PROX);
while(CapSense_IsBusy())
{
/* Put the PSoC 4200M in Sleep power mode while the CapSense is scanning.
* The device wakes up using the interrupt generated by CapSense CSD Component
* after scanning. */
}
/* Check if proximity sensor is active. */
proximity = CapSense_CheckIsSensorActive(CapSense_PROXIMITYSENSOR__PROX);
if(proximity == ACTIVE)
{
/* Set the LED at a brightness level corresponding
* to the proximity distance. */
if(sw==0){
PWM_1_WritePeriod(400);
PWM_1_WriteCounter(0);
PWM_1_Start(); // Start rolling dice
sw=1;
}
}
else /* Proximity sensor is inactive. */
{
if(sw==1){
/* Roll dice slowly */
PWM_1_WritePeriod(1000);
PWM_1_WriteCounter(0);
CyDelay(1500); // keep rolling slowly for 1.5sec
PWM_1_Stop();// Stop rolling dice
sw=0; // sw is off
}
}
}
}
The dice rolls when you hold your hand over the proximity sensor, and the dice slowly rolls when you move it away, and then stops.
Thanks,
Kenshow
Show LessHi,
こんばんは、
I'm going to teach a 10 days FPGA design course starting from next Monday.
And during the course I'm also planning to teach the basic hands on of PSoC 4 (CY8CKIT-044).
So I was browsing sample projects and I found that "CY8CKIT-044 Sensor Hub" is very nice.
But it requires Micrium uC-Probe to show its best.
Although uC-Probe is free download, after 45 days it may require additional cost.
So I decide to hack-up a more affordable sample for students.
来週から10日間の FPGA 実習講座を教えるのですが、その中で PSoC 4 (CY8CKIT-044) を使用したハンズオンも企んでいます。
何か良さそうなサンプルないかなとみていたら、キットについてくるサンプルの "CY8CKIT-044 Sensor Hub" がとても良さそうなのですが、
Micrium uC-Probe 経由でないと一番格好の良いところは見せられそうもありません。
uC-Probe って、ダウンロード時は無償なのですが、45日経つと無償期間が終わってしまうようなので、
学生さん向けに、もう少しお財布にやさしいデモにでっち上げてみました。
Although the original example project was using WDT I chose SysTick.
So that it will be easier to change the interval(s) of each sensors.
I cheated by using my previous samples
元サンプルは WDT を使用してタイミングをとっていましたが、各センサーのインターバルを
変更しやすいように SysTick を使用しました。
また、先に投稿してあった下記のサンプルを使用して、少し楽をさせてもらいました。
tty_utils a utility sample for CLI type program
https://community.cypress.com/message/200391#200391
A simple VT100 Escape Sequence Emulator
https://community.cypress.com/message/188161#188161
RTC with 32kHz Crystal Sample
https://community.cypress.com/thread/54092
schematic / 回路図
pins / ピンアサイン
main.c
========================
#include "project.h"
#include "stdio.h"
#include "tty_utils.h"
#include "vt100.h"
#include "rtc_utils.h"
#include "main.h"
#include "accelerometer.h"
/*****************************************************************************
* Local Function Prototypes
*****************************************************************************/
CY_ISR_PROTO(Accelerometer_Interrupt);
CY_ISR_PROTO(SW2_Pressed) ;
CY_ISR_PROTO(SysTick_ISR) ;
#define LOC_DATE_X 20
#define LOC_DATE_Y 4
#define LOC_TEMP_X 10
#define LOC_TEMP_Y 8
#define LOC_AMB_X 40
#define LOC_AMB_Y 8
#define LOC_ACC_X 10
#define LOC_ACC_Y 12
#define LOC_ACCX_X 16
#define LOC_ACCY_X 28
#define LOC_ACCZ_X 40
/*****************************************************************************
* Global Variable Declarations
*****************************************************************************/
int16 ambientLight = ZERO;
int8 temperatureInteger = ZERO;
int16 x_dirMovement = ACC_NO_MOVEMENT;
int16 y_dirMovement = ACC_NO_MOVEMENT;
int16 z_dirMovement = ACC_NO_MOVEMENT;
uint8 temperatureFractional = ZERO;
uint8 acclerometer_configured = FALSE;
uint8 accRequest = FALSE;
uint8 oneSecondTrigger = FALSE;
uint8 displayErrorOnce = FALSE;
int rtc_configured = FALSE ;
volatile int g_redraw = TRUE ;
volatile uint32_t g_tick_count = ZERO ;
volatile int sec_flag = FALSE;
volatile int acc_flag = FALSE ;
volatile int temp_flag = FALSE ;
volatile int light_flag = FALSE ;
char *temp_title = "Temperature: " ;
char *amb_title = "Ambient Light: " ;
char *acc_title = "Acc:" ;
char *accx_title = "X: " ;
char *accy_title = "Y: " ;
char *accz_title = "Z: " ;
int temp_title_len = ZERO ;
int amb_title_len = ZERO ;
int acc_title_len = ZERO ;
int accx_title_len = ZERO ;
int accy_title_len = ZERO ;
int accz_title_len = ZERO ;
void draw_frame(void)
{
splash("CY8CKIT-044 Sensor Test") ;
locate(LOC_TEMP_X, LOC_TEMP_Y) ;
print(temp_title) ;
temp_title_len = strlen(temp_title) ;
locate(LOC_AMB_X, LOC_AMB_Y) ;
print(amb_title) ;
amb_title_len = strlen(amb_title) ;
locate(LOC_ACC_X, LOC_ACC_Y) ;
print(acc_title) ;
acc_title_len = strlen(acc_title) ;
locate(LOC_ACCX_X, LOC_ACC_Y) ;
print(accx_title) ;
accx_title_len = strlen(accx_title) ;
locate(LOC_ACCY_X, LOC_ACC_Y) ;
print(accy_title) ;
accy_title_len = strlen(accy_title) ;
locate(LOC_ACCZ_X, LOC_ACC_Y) ;
print(accz_title) ;
accz_title_len = strlen(accz_title) ;
}
int find_empty_slot(void)
{
int result = -1 ;
uint32_t i ;
for (i = 0 ; i < CY_SYS_SYST_NUM_OF_CALLBACKS ; i++ ) {
if (CySysTickGetCallback(i) == NULL) {
result = i ;
break ;
}
}
return(result) ;
}
void do_acc(void)
{
/* Dummy variable to read the interrupt release register of accelerometer. */
uint8 dummy = ZERO;
if (accRequest == TRUE && acclerometer_configured == TRUE) {
accRequest = FALSE;
/* Read the accelerometer data and update the global variables. */
ReadAccelerometer(&x_dirMovement, &y_dirMovement, &z_dirMovement);
/* Read interrupt release register to clear the latched interrupt. */
Accelerometer_RegRead(ACC_INT_REL, &dummy);
}
locate(LOC_ACCX_X + accx_title_len, LOC_ACC_Y) ;
snprintf(str, STR_BUF_LEN, "%5d", x_dirMovement) ;
print(str) ;
locate(LOC_ACCY_X + accy_title_len, LOC_ACC_Y) ;
snprintf(str, STR_BUF_LEN, "%5d", y_dirMovement) ;
print(str) ;
locate(LOC_ACCZ_X + accz_title_len,LOC_ACC_Y) ;
snprintf(str, STR_BUF_LEN, "%5d ", z_dirMovement) ;
print(str) ;
}
void do_temp(void)
{
/* Local Variables */
uint8 tempError = FALSE;
int16 temperatureReturnVal = ZERO;
/* Check if temperature measurement is complete. */
tempError = Temperature_Sense_ConversionStatus();
/* If conversion is complete, update the temperature variable. */
if((tempError & Temperature_Sense_STATUS_COMPLETE) == Temperature_Sense_STATUS_COMPLETE) {
/* Read the temperature value. */
temperatureReturnVal = Temperature_Sense_GetTemperature(DEFAULT_SENSOR);
/* Temperature measured is in 1/100th of a degree Celsius.
* Scale the value for comfortable viewing on UART. */
temperatureInteger = temperatureReturnVal/DIVISOR_HUNDRED;
/* Find the fractional part of temperature data for logging in the F-RAM. */
if(temperatureReturnVal < ZERO) {
temperatureFractional = DIVISOR_HUNDRED - temperatureReturnVal%DIVISOR_HUNDRED;
} else {
temperatureFractional = temperatureReturnVal%DIVISOR_HUNDRED;
}
/* Trigger next conversion when the current conversion is complete. */
Temperature_Sense_Trigger();
}
locate(LOC_TEMP_X + temp_title_len, LOC_TEMP_Y) ;
snprintf(str, STR_BUF_LEN, "%d.%d ", temperatureInteger, temperatureFractional) ;
print(str) ;
}
void do_light(void)
{
locate(LOC_AMB_X + amb_title_len, LOC_AMB_Y) ;
snprintf(str, STR_BUF_LEN, "%hd ", ambientLight) ;
print(str) ;
}
void update_time(void)
{
locate(LOC_DATE_X, LOC_DATE_Y) ;
print_date() ;
print(" ") ;
print_time() ;
print(" ") ;
}
int main(void)
{
Initialize_Project() ;
for(;;) {
if (g_redraw) {
draw_frame() ;
g_redraw = FALSE ;
}
if (acc_flag) {
do_acc() ;
acc_flag = FALSE ;
}
if (temp_flag) {
do_temp() ;
temp_flag = FALSE ;
}
if (light_flag) {
do_light() ;
light_flag = FALSE ;
}
if (sec_flag) {
update_time() ;
sec_flag = 0 ;
}
}
}
/*******************************************************************************
* Function Name: Initialize_Project
********************************************************************************
* Summary:
* Starts and initializes all the Components in the project. Enables
global interrupt.
*
* Parameters:
* void
*
* Return:
* void
*
*******************************************************************************/
void Initialize_Project(void)
{
int sys_tick_slot = 0 ;
/* Enable global interrupt. */
CyGlobalIntEnable;
/* Start the Opamp hardware. */
Opamp_Start();
/* Enable and start ADC block. */
ADC_Start();
/* Enable the DMA Component. This API also sets the
* source and destination addresses. */
DMA_Start((void *)ADC_SAR_CHAN0_RESULT_PTR, (void *)&ambientLight);
/* Start ADC conversions. */
ADC_StartConvert();
/* Enable and start accelerometer I2C block. */
I2C_Start();
/* Enable the interrupt from accelerometer. */
isr_Accelerometer_Interrupt_StartEx(Accelerometer_Interrupt);
/* Start the TMP05 temperature sensor Component. */
Temperature_Sense_Start();
/* Trigger the temperature sensor Component to start measurement. */
Temperature_Sense_Trigger();
/* Enable and start UART communication block. */
tty_init() ;
/* Wait for 50ms for the accelerometer to start up. */
CyDelay(ACC_STARTUP_TIME);
sys_tick_slot = find_empty_slot() ;
if (sys_tick_slot < 0) {
print("Sorry No empty SysTick Slot available\n\r") ;
while(1) { } /* halting here */
} else {
CySysTickStart() ;
CySysTickSetCallback(sys_tick_slot, SysTick_ISR) ;
}
/* Initialize the accelerometer after a self-test. */
InitializeAccelerometer();
sw2_int_ClearPending() ;
sw2_int_StartEx(SW2_Pressed) ;
cls() ;
setup_time() ;
}
CY_ISR(Accelerometer_Interrupt)
{
accRequest = TRUE;
Pin_Accelerometer_Interrupt_ClearInterrupt();
}
CY_ISR_PROTO(SW2_Pressed)
{
g_redraw = TRUE ;
SW2_ClearInterrupt() ;
}
CY_ISR(SysTick_ISR)
{
g_tick_count++ ;
if ((g_tick_count % 100) == 0) { /* 0.1 sec */
acc_flag = TRUE ;
if ((g_tick_count % 1000) == 0) { /* 1 sec */
sec_flag = TRUE ;
light_flag = TRUE ;
temp_flag = TRUE ;
g_tick_count = 0 ;
}
}
}
========================
Tera Term output / Tera Term 出力
When the program starts, it asks for date and time.
起動すると、日付と時間の入力が要求されます。
When date and time were given, program starts polling the sensor(s)
日時の設定が終わるとプログラムは各センサの値を表示します。
But as the program only rewrites the value, if you scroll or resize the window, titles will be lost.
プログラムは値のみアップデートしていますので、ターミナルをスクロールしたり
リサイズしたりすると値のタイトルが消えてしまいます。
Push SW2 to redraw the titles.
その場合には、SW2 を押すとタイトルが再表示されます。
moto
基
19-Aug-2020 Edited to correct some English.
Show LessA while ago, one of my colleagues was missing an oscilloscope during he is working from home.
Since the required bandwidth was a few KHz, I tried to create one for him, but I could not make it work well.
(Mainly I could not control the display of SerialPlotter)
Then yesterday, I made a mistake by asking if the students who will take my course starting from tomorrow have access to oscilloscope(s).
Since they also are going to work (study?) from home, naturally the answer was NO. orz
The remaining time was 1 day and a half.
Yes, it was a time for another hack! o(^_^)V
少し前にテレワークしている同僚がオシロ欲しいよ~とこぼしていました。
彼のアプリで必要なバンド幅は数KHz 程度だったので、プログラム書けないかなと試してみたのですが、
なかなか思うように行きませんでした。(主に SerialPlotter の表示を固定するのが上手くいかず・・・)
そんな中、明日から始まる大学の講習について、誤って昨日、学生さんオシロ使える状態ですよね?と質問してしまったところ
彼らもテレワークなので、当然ながら回答は NO でした。orz
残された時間は後一日半、さぁ、ハッキングの時間だぜぃ! と思いました。o(^_^)V
So the theme of the day is a simple oscilloscope using a CY8CKIT-044 and SrialPlotter as the display.
Fortunately all the students have a CY8CKIT-044 and USB-Serial Converter.
という訳で、今回のお題は、CY8CKIT-044 と SerialPlotter を使用して簡易オシロをでっち上げること!
幸い受講生の皆さんには CY8CKIT-044 と USB-Serial コンバータは配布済みでした。
This program uses the UART of KitProg as DATA_OUT for SerialPlot.
And I added another UART for user interface.
このプログラムでは KitProg 側の UART を SerialPlot 用の DATA_OUT として使用します。
その為、ユーザーインタフェース用に UART を追加しました。
schematic / 回路図
pins / ピンアサイン
command list / ヘルプメニュー
When program starts, a splash title and prompt appears on the UART terminal.
Type "help" for command menu.
プログラムを起動すると、簡単なタイトルとプロンプトが表示されます。
“help” と入力するとコマンド一覧が表示されます。
trig : trigger setting
trig <ch> <mode> <level> <pos>
<ch> the channel to set trigger
<mode> one of "rise", "fall", "level", "none"
<level> the value checked against the trigger. Currently this is the raw count value of ADC
so the value would be 0 ~ 2047 or so.
<pos> where in the screen placed the trigger point
trig: トリガー設定
trig <チャネル> <モード> <閾値> <位置>
<チャネル> トリガーを設定するチャネル
<モード> "rise" (立上がり) "fall" (立下り) "level" (値) "none" (トリガ無し)
<閾値> トリガを判定の値。現在は ADC の raw カウントをそのまま使用しています、
その為 0+2047 が有効な値になります。
<位置> SerialPlotter の画面上左からどのくらいの位置にトリガを配置するかを設定します。
len: Specify the number of data in one screen
len <value>
<value> must be 1 ~ 1024、this value must match with the Plot Width of SerialPlotter
len: 一画面のデータ数
len <数>
<数> 一画面に表示されるデータ数を指定します。この値は SerialPlotter の Plot Width と合わせてください。
ch: set the number of channels
ch <number>
<number> of channels 1 or 2
ch: チャネル数の設定
ch: <チャネル数>
<チャネル数> チャネルの数、現ヴァージョンでは 1 ~ 2
offset: set DC offset of a channel
offset <bias>
<bias> the value to shift the channel vertically in the SerialPlotter
offset: チャネルの縦位置調整
offset <バイアス>
<バイアス> SerialPlotter の画面上で縦に移動させる値
sample: set the interval of sampling
sample <sample_interval>
<sample_interval> 1(/sampling freq) default is 10 us/cycle = 100000.00 Hz = 100kHz
sample: サンプリング間隔の設定
sampe <サンプル間隔>
<sample間隔> 1/(サンプリング周波数) デフォルトでは 10us/cycle で 100kHz サンプリングになっています。
run: Run the program / 測定動作の開始または再開
stop: Stop the program / 測定動作の停止
sw2 can be used instead of run/stop / sw2 を押すことでも run/stop と同様の動作をさせることができます。
Note: While running, UART input is not working well, so I recommend to use sw2 instead.
注意:測定動作中は UART からの受信が不安定になりますので、代わりに sw2 を使用してください。
status: show current status / 現在のステータスの表示
single: Single Shot Mode / シングルショットモード
Measure only 1 screen full data including the trigger point and stop measurements.
トリガを含む一画面分の測定を行い停止する。
repeat: Repeat Mode / 連続モード
Repeat measurements.
測定を複数画面にわたり繰り返す。
interval: set interval between each screen measurement / 測定単位(画面)間の待ち時間
interva <time>
<time> : interval between screens in ms. / 画面間の待ち時間 (ms)
pwm: config test pwm signal output / テスト用 pwm 信号の設定
pwm <period> <compare>
<period> : period in us / 周期 (us)
<compare>: duty width / デューティ幅の設定
index: enable/disable an additional sweep signal to check the phase of screen.
index { 0 | 1 }
0: hide index signal, only ch number of signals will be generated
1: show index signal, 0 to num_data sweep signal will be generated
this is a utitilty function to check if the signal and SerialPlotter screen is in sync
index: 画面の位相確認用のスウィープ信号の発生
index { 0 | 1 }
0: スウィープ信号を発生しません。
1: スウィープ信号を発生します、表示チャネルは指定したチャネル数+1になります。
SerialPlotter screen with PWM test signal and signal from a FuncGen program of FRDM-KL25Z
Note: Trigger Pos is 512 and at the Rising Edge of channel 1 (which is the output of test PWM)
FRDM-KL25Z 上で動作しているファンクジェンとテスト用PWMの出力を観測した SerialPlotter の画面。
トリガは PWM 出力の上りエッジにかけて、左から 512 ポイントの位置に表示されるように
設定されています。
SerialPlotter screen with DE10-Lite FPGA board running simple counter program.
The clock input is a push switch (KEY1)
ED10-Lite FPGA 基板にて簡単なカウンタプログラムを動作させて場合の SerialPlotter 画面。
カウンタのクロック入力はプッシュスイッチ (KEY1) になっています。
Upper signal is raw input from the push switch.
Lower signal is "debounced" signal of the push switch
上の信号がプッシュスイッチからの生の信号
下の信号がデバウンスを通した後の信号
moto
P.S. As written in the introduction, this is a one day hack. So please do not expect perfect flawless stuff.
追伸:冒頭にありますように、一日のやっつけ仕事です、間違っても完全・完璧などは期待しないでください。
Show LessHi.
This sample uses CY8CKIT-149.
This sample displays the Cp values of each buttons to the serial terminal at start up.
After that button press(es) will be reflected to the corresponding LEDs.
I hope this sample helps in evaluating CapSense.
schematics
Pin list
main.c
====================================================================
/*******************************************************************************
* Included Headers
*******************************************************************************/
#include "CapSense.h"
#include <project.h>
#include "stdio.h"
/*****************************************************************************
* MACRO Definitions
*****************************************************************************/
#define LED_ON (0u) /* Pin state to turn ON an active-LOW LED */
#define LED_OFF (1u) /* Pin state to turn OFF an active-LOW LED */
/* Finite state machine for device operating states
SENSOR_SCAN - Sensors are scanned in this state
WAIT_FOR_SCAN_COMPLETE - CPU is put to sleep in this state
PROCESS_DATA - Sensor data is processed, LEDs are controlled,
and I2C buffer is updated in this state */
typedef enum
{
SENSOR_SCAN = 0x01u,
WAIT_FOR_SCAN_COMPLETE = 0x02u,
PROCESS_DATA = 0x03u,
} DEVICE_STATE;
/*****************************************************************************
* Function Prototypes
*****************************************************************************/
void TestSensorCapacitance(void) ; /* same with CapSense_RunSelfTest(CapSense_TST_SNS_CAP) ; */
void cls() ;
void print(char *str) ;
#define STR_LEN 64
char str[STR_LEN+1] ;
int main()
{
/* Variable to hold the current device state
* State machine starts with Sensor_Scan state after power-up
*/
DEVICE_STATE currentState = SENSOR_SCAN;
/* Enable global interrupts. */
CyGlobalIntEnable;
//sizeof(CapSense_dsRam),
//(uint8_t *)&(CapSense_dsRam));
CapSense_Start(); /* Initialize Component */
/*CapSense Cp value check */
CapSense_RunSelfTest(CapSense_TST_RUN_SELF_TEST_MASK) ;
UART_Start() ;
print("CapSense cp\n ") ;
snprintf(str, STR_LEN, "BTN0(%d) BTN1(%d) BTN2(%d) \n\r",
CapSense_BTN0_SNS_CP0_VALUE , CapSense_BTN1_SNS_CP0_VALUE, CapSense_BTN2_SNS_CP0_VALUE ) ;
print(str) ;
for(;;)
{
/* Switch between SENSOR_SCAN->WAIT_FOR_SCAN_COMPLETE->PROCESS_DATA states */
switch(currentState)
{
case SENSOR_SCAN:
/* Initiate new scan only if the CapSense block is idle */
if(CapSense_NOT_BUSY == CapSense_IsBusy())
{
#if ENABLE_TUNER
/* Update CapSense parameters set via CapSense tuner before the
beginning of CapSense scan
*/
CapSense_RunTuner();
#endif
/* Scan widget configured by CSDSetupWidget API */
CapSense_ScanAllWidgets();
/* Set next state to WAIT_FOR_SCAN_COMPLETE */
currentState = WAIT_FOR_SCAN_COMPLETE;
}
break;
case WAIT_FOR_SCAN_COMPLETE:
/* Put the device to CPU Sleep until CapSense scanning is complete*/
if(CapSense_NOT_BUSY != CapSense_IsBusy())
{
CySysPmSleep();
}
/* If CapSense scanning is complete, process the CapSense data */
else
{
currentState = PROCESS_DATA;
}
break;
case PROCESS_DATA:
/* Process data on all the enabled widgets */
CapSense_ProcessAllWidgets();
/* Controls LEDs Status based on the result of Widget processing. */
LED_13_Write(CapSense_IsWidgetActive(CapSense_BTN0_WDGT_ID) ? LED_ON : LED_OFF );
LED_12_Write(CapSense_IsWidgetActive(CapSense_BTN1_WDGT_ID) ? LED_ON : LED_OFF );
LED_11_Write(CapSense_IsWidgetActive(CapSense_BTN2_WDGT_ID) ? LED_ON : LED_OFF );
/* Set the device state to SENSOR_SCAN */
currentState = SENSOR_SCAN;
break;
/*******************************************************************
* Unknown power mode state. Unexpected situation.
******************************************************************/
default:
break;
}
}
}
void cls(void)
{
print("\033c") ; /* reset */
CyDelay(20) ;
print("\033[2J") ; /* clear screen */
CyDelay(20) ;
}
void print(char *str)
{
UART_UartPutString(str) ;
}
/* [] END OF FILE */
====================================================================
Thanks,
Asanuma
Show Less