Code Examples Forum Discussions
最近、私の同僚が CapSense のデモ用に設計してエレファンテック社にオーダーしたフレキのセンサー電極を少し分けてもらうことができました。
https://www.elephantech.co.jp/
Recently one of my colleague gave me a few sensor electrode of flex PCB he designed and ordered to Elephantech.
https://www.elephantech.co.jp/en/
フレキと標準の変換は下記基板を入手して使いました。
I used an adapter from the URL below
https://www.aitendo.com/product/19419
最初、CY8CKIT-043 でも試してみたのですが、EZI2C を使用した CapSense Tuner と
KitProg 経由 UART の相性があまり良くない気がしたので、いつもの CY8CKIT-044 に乗り換えて
以前買ってあった Adafruit の TFT を使用しました。
※ ILI9341/SPI/QVGA タイプの TFT であれば他のものでも使えると思います。
https://learn.adafruit.com/adafruit-2-8-tft-touch-shield-v2
At first I tried with CY8CKIT-043, but I found that EZI2C used for the CapSense Tuner and UART via KitProg do not go well, so I changed the hourse to my trusty CY8CKIT-044 and used the Adafruit TFT, which I purchased before.
Note: Probably any TFT with ILI9341/SPI/QVGA can work, too.
https://learn.adafruit.com/adafruit-2-8-tft-touch-shield-v2
Launching the CapSense Tuner / キャップセンス チューナーを起動します
CapSense Tuner started / キャップセンス チューナーが立ち上がりました
Click "Connect" icon in the top left / 左上にある "Connect" ボタンを押します
接続されるとボタンは "Disconnect" という表示に変わります。
The button changes to "Disconnect" when connection is established.
次に "Start" アイコンを押します。(私はいつもこれを忘れてしまいます。orz)
チューナーの動作が開始されると表示が "Stop" に変わります。
Then click "Start" icon. (Note: I always forget this >_< )
The button changes to "Stop" when the tuner started working.
ボタン1にタッチした状態
When button1 is touched
ボタン2にタッチした状態
When button2 is touched
ボタン3にタッチした状態
When button3 is touched
表示を GraphView タブに変えた時
Switching to the GraphView Tab
評価基板上のキャップセンス電極が機能するのは当然と言えるかも知れませんが、
他の電極を接続しても、殆ど手間いらずでボタンを検知できる SmartSense の機能は
ありがたいものだと思いました。
Although it is natural that EVB's on board electrodes work OK, when connecting other electrode and it works without any tuning nor hustle seems to be a great benefit of the SmartSense functionality.
schematic / トップレベル回路図
CapSense Configuration / キャップセンスの設定
各ボタン電極のチューニング実験をしてみたかったので
本来は一つのウィジェットで3つボタンの設定でも行けるのですが
あえて三つのウィジェットに各ボタンを割り振ってみました。
As I was planning to play with tuning each button electrode,
I assigned each button to different widgets.
It should work with one widget of 3 buttons, though.
Pins / ピン設定
main.c
#include "project.h"
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "TFT.h"
#include "Arial12x12.h"
#include "Arial28x28.h"
#define USE_TUNER 1u
#define STR_BUF_LEN 64
char str[STR_BUF_LEN+1] ;
typedef struct _button {
int value ;
int x ;
int y ;
int w ;
int h ;
} Button_Type ;
#define BUTTON_WIDTH 70
#define BUTTON_HEIGHT 70
Button_Type button[3] = {
{ 0, 30, 70, 70, 70 },
{ 0, 130, 70, 70, 70 },
{ 0, 230, 70, 70, 70 }
} ;
typedef struct I2CRamBuffer
{
uint16 u16_rawdata[CapSense_TOTAL_SENSORS];
uint16 u16_baseline[CapSense_TOTAL_SENSORS];
uint16 u16_signal[CapSense_TOTAL_SENSORS];
uint8 u8_sensorStatus;
} I2CRamBuffer;
void draw_button(Button_Type *button, uint16_t color)
{
TFT_fillrect(button->x, button->y, button->x + button->w, button->y+button->h, color) ;
}
void init_hardware(void)
{
CyGlobalIntEnable; /* Enable global interrupts. */
#if USE_TUNER
EZI2C_Start() ;
EZI2C_EzI2CSetBuffer1(
sizeof(CapSense_dsRam),
sizeof(CapSense_dsRam),
(uint8_t *)&(CapSense_dsRam)) ;
#endif
TFT_CS_Write(1) ;
TFT_DC_Write(0) ;
TFT_BL_Write(0) ;
SPI_Init() ;
SPI_Start() ;
TFT_BusEnable(1) ;
TFT_Init() ;
TFT_foreground(White) ;
TFT_background(Black) ;
TFT_BusEnable(1) ;
TFT_cls() ;
TFT_BusEnable(0) ;
TFT_BL_Write(1) ;
CapSense_Start() ;
CapSense_ScanAllWidgets() ;
}
int doCapSense(Button_Type *button)
{
int result = 0 ;
if (CapSense_NOT_BUSY == CapSense_IsBusy()) {
CapSense_ProcessAllWidgets() ;
#if USE_TUNER
CapSense_RunTuner() ;
#endif
if (CapSense_IsWidgetActive(CapSense_BUTTON0_WDGT_ID)) {
button[0].value = CapSense_IsSensorActive(CapSense_BUTTON0_WDGT_ID, CapSense_BUTTON0_SNS0_ID) ;
result = 1 ;
} else {
if (button[0].value != 0) {
button[0].value = 0 ;
result = 1 ;
}
}
if (CapSense_IsWidgetActive(CapSense_BUTTON1_WDGT_ID)) {
button[1].value = CapSense_IsSensorActive(CapSense_BUTTON1_WDGT_ID, CapSense_BUTTON1_SNS0_ID) ;
result = 2 ;
} else {
if (button[1].value != 0) {
button[1].value = 0 ;
result = 2 ;
}
}
if (CapSense_IsWidgetActive(CapSense_BUTTON2_WDGT_ID)) {
button[2].value = CapSense_IsSensorActive(CapSense_BUTTON2_WDGT_ID, CapSense_BUTTON2_SNS0_ID) ;
result = 4 ;
} else {
if (button[2].value != 0) {
button[2].value = 0 ;
result = 4 ;
}
}
}
CapSense_ScanAllWidgets() ;
return( result ) ;
}
int prev_button[3] = { 0, 0, 0} ;
void draw_a_button(Button_Type *button)
{
TFT_BusEnable(1) ;
TFT_set_font(Arial12x12) ;
TFT_locate(button->x + 25, button->y + 30) ;
if (button->value) {
draw_button(button, Yellow) ;
TFT_background(Yellow) ;
TFT_foreground(Black) ;
TFT_putstr("ON ") ;
} else {
draw_button(button, Blue) ;
TFT_background(Blue) ;
TFT_foreground(White) ;
TFT_putstr("OFF") ;
}
CyDelay(10) ;
TFT_BusEnable(0) ;
}
void draw_buttons(Button_Type *button)
{
int i = 0 ;
for (i = 0 ; i < 3 ; i++ ) {
draw_a_button(&button[i]) ;
}
}
int main(void)
{
int i ;
init_hardware() ;
draw_buttons(button) ;
for(;;) {
if (doCapSense(button)) {
for (i = 0 ; i < 3 ; i++ ) {
if (button[i].value != prev_button[i]) {
draw_a_button(&button[i]) ;
prev_button[i] = button[i].value ;
}
}
}
}
}
moto
Show Less
Hi,
Here I submitting my version of the 24-bit DDS arbitrary frequency generator component. It is useful for applications requiring precision frequency generation. Provided below are: component library, datasheet, application note and several demo projects exemplifying use of the component.
Many thanks to authors of various previous incarnations of DDSs: <PSoC73>, <pavloven>, <vdvorak>, <kabron>, <JLS1>.
This component was developed as part of Warp Verilog study and does not pursue any particular purpose.
odissey1
video link: DDS tunable frequency / phase generator using Cypress PSoC5 - YouTube
Show Less
Hello....
Starting with Cypress controller, what development kit or code examples helps me to develop small test application to verify the proper working of UART, SPI, I2C, GPIO, Clocks etc. peripherals.??
I have IAR 8.4 Workbench IDE for programming and debugging code, so looking for example codes in IAR IDE support.
Show LessI've attached a project that has DMA-driven function equivalents for:
- memset() => dmemset()
- memcpy() => dmemcpy()
- memmove() => dmemmove()
It uses a single DMA channel and TD resource for these functions.
The reason for this project is to see how much faster the transfer of data can occur from these replacement functions.
Summary: Transfer sizes 64 bytes or above (@ BUS_CLK = 72 MHz) are faster than the standard string library equivalents.
At a transfer size of 4095 bytes (maximum DMA TD transfer count), the transfer time is over 7 times faster!
This project is written for a PSoC5 but can easily be converted to other PSoC families that have DMA resources.
I welcome any suggestions for improvements.
I'm also considering making this into an installable component. Your thoughts.
Enjoy!
Show Less
Hi,
We have connected psoc 5 usb pins to an arm based board .I want to know if there is any boot tool in Linux which we can use to flash the board.
Regards,
Madhav
Show Less
Hi,
Uploaded below is a demo project showing 16-bit PWM DAC using 8-bit Fractional PWM and 8-bit Delta-Sigma Modulator and simple RC-filter.
The PWM DACs are popular in budget audio applications due to their simplicity. The known issue of this approach is very slow response due to the necessity to filter out the main PWM harmonic: PWM_Clock / 2^N, where N - is the number of PWM bits. For 16-bit PWM, and clock frequency of 48MHz, this results in 48MHz / 2^16 = 732 Hz, which is rather slow for audio use. For 8-bit PWM, the main lobe is located at 48MHz / 2^8 = 187.5 kHz, which is acceptable for audio applications. Unfortunately, 8-bit output amplitude is not nearly enough in most cases. The project below tries to resolve this dilemma by using fast 8-bit Fractional PWM, where output duty cycle is externally switched between the (MSB) and (MSB+1) positions using custom Delta-Sigma Modulator. The PWM provides the MSB (most significant bit), while Delta-Sigma Modulator provides the LSB. This way the PWM can operate at high frequency of 187.5kHz, while the DeltaSigma Modulator provides extra bits of resolution.
As usual with PWM DACs, the absolute accuracy depends on the stability of the driving voltage Vdd, output buffer speed and symmetry against Vdd and Vss (Gnd). Any fluctuations on the power rail directly affect the DAC output. Simple RC filter provides -43dB suppression of the PWM main harmonic. Using (pseudo-) second-order filter, made of two RC filters in series, suppresses it below -75dB.
Attached are two projects: basic and extended. The basic project includes all necessary components, and simply outputs a single voltage. The extended project scans the output from 0-65535, and uses ADC for sampling the DAC values and displaying them using SerialPlot charting software.
/odissey1
Projects include modified 1-st-order Delta-Sigma Modulator, originally developed by FY_ZHU
Extended project also uses additional custom components:
SerialPlot v0.0: Interface to real-time data charts
PSoC Annotation Library v1.0 (optional)
Figure1. Fractional PWM DAC using 8-bit PWM modulated by 1-st order 8-bit DeltaSigma Modulator
Figure 2. PWM output is filtered by simple 1-st order RC filter with R1=2.2k, C1=100nF.
Figure 3. Project annotation using PSoC Annotation Library v1.0. The ADC serves as a voltmeter. The physical connection between Pin 12.7 (UART TX) and the SerialPlot charting software is not required.
Figure 4. SerialPlot output while scanning DAC code 0 to 65500. Blue - DAC code, Red - result measured by ADC, Green - residual (ADC sample - DAC Code). R1=2.2k.
Figure 5. SerialPlot output of the residual (ADC sample - DAC code) for R1=2.2k. Note that the shape of the curve varies with R1 value. The noise is due to the Vdd instability of the USB-powered PSoC prototyping board.
Figure 6. SerialPlot output of the residual (ADC sample - DAC code) for R1=1.0k.
Figure 7. SerialPlot output of the residual (ADC sample - DAC code) for R1=4.7k.
Figure 8. FFT of the AC-coupled DAC output at mid-scale (DAC code = 32767), after single RC filter (R1=2.2k, C1=100nF). The PWM at 187.5 kHz p-p is ~40mV (-43dB). The noise floor is at about -75dB.
Figure 9. FFT of the AC-coupled DAC output at mid-scale (DAC code = 32767), filtered using double serial filter R1C1-R2C2 (R1=2.2k, C1=100nF, R2=2.2k, C2=100nF). The PWM noise at 187.5 kHz is not discernible above the noise floor (-75dB).
Show Less
In the discussion below,
下記のスレッドで
I suggested to see my CY8CKIT-059 version of this program
CY8CKIT-059 版のこのプログラムを参照していただくようにレスしました。
But as the intention of this program was to show basic usage of peripherals for those new to PSoC,
I regret that pointing a project which requires device change and pin assignments change.
So trying to be nicer, I ported this to CY8CKIT-050 (CY8C5868AXI-LP035).
しかし、元々初めて PSoC を使う人に基本的なペリフェラルの使用方法をお見せするという
このプログラムの意図からすると、基板が異なり、デバイスとピンアサインを変更しなくては
行けないプロジェクトをお知らせするのは不親切だったなと壁に向かって反省しました。
というわけで、CY8CKIT-050 (CY8C5868AXI-LP035) に移植したのがこのバージョンです。
Then the bad news is that I'm not be able to afford time to write usage of this program again,
so please refer to the CY8CKIT-059 version for the usage.
さて、悪い知らせとしては、このプログラムの使用方法を再度書く時間がなさそうですので、
下記の CY8CKIT-059 版での使用方法をご参照ください。
The good news is that CY8CKIT-050 has more parts mounted,
so you can use
on board POT for the input of ADC,
pwm output is connected to LED (P6[3])
gpio input is SW2 (P6[1])
gpio output is LED (P6[2])
UART is assigned to P12[6] (rx) P12[7] tx
一方、良い知らせとしては、CY8CKIT-050 には CY8CKIT-059 よりも沢山の部品が搭載されていますので
ADC 入力としては基板上の POT
PWM の出力には LED (P6[3])
GPIO 入力としては SW2 (P6[1])
GPIO 出力としては LED(P6[2])
が使えるようになっています。
また、UART は P12[6] (rx) P12[7] (tx) に割り当ててあります。
moto
Show Less
Hi,
There has been a question (request?) of RC5 IR remote receiver.
https://community.cypress.com/t5/PSoC-4-MCU/IR-interfacing-with-Capsense-Button/m-p/272229#M39274
And by googling the web I found many reference information such as
https://techdocs.altium.com/display/FPGA/Philips+RC5+Infrared+Transmission+Protocol
Then what I noticed was that the standard is usually not in use in Japan,
anyway as I don't watch TV so I don't have a remote control handy 😜
To make and test the receiver, I also needed an emulator of the remote control >_<
So I created an RC5 remote control emulator on CY8CKIT-044 and a sample receiver on CY8CKIT-042.
On CY8CKIT-044 (RC5 Remote Emulator),
when I typed 0 5 53 (which is toggle = 0, address = 5, command = 53 (35h)) similar to the reference site
the waveform on my oscilloscope seemed to be OK.
Note: I emulated the output signal of IRM-36xx, not the real IR light.
Probably if I AND this signal with the carry pulse, IR light like signal could be generated,
but I did not go that far.
Then I connected CY8CKIT-042 and CY8CKIT-044 using
GND-GND
P0[1] - P0[1]
And when I typed below in the Tera Term connected to CY8CKIT-044 (remote control)
CY8CKIT-044 (RC5 remote control emulator)
CY8CKIT-042 (receiver) showed
So they seem to communicate OK.
CY8CKIT-044 (RC5 remote control emulator)
schematic
pins
main.c
============================
#include "project.h"
#include "stdio.h"
#include "tty_utils.h"
#define RC5_ONE 0x01
#define RC5_ZERO 0x02
#define RC5_CLK_PER_BIT 2
void init_hardware(void)
{
CyGlobalIntEnable; /* Enable global interrupts. */
ShiftReg_Init() ;
tty_init() ;
}
void print_data(uint32_t data)
{
uint32_t mask = (0x01 << 27) ; /* 14 x 2 x halfbits */
while(mask) {
if (mask & data) {
print("1") ;
} else {
print("0") ;
}
mask >>= 1 ;
}
print("\n") ;
}
void send_ir(int toggle, int address, int command)
{
uint32_t data = 0x16 ; /* 010110 */
uint32_t mask ;
// Start Bit 1
data = RC5_ONE ;
// Start Bit 2
data <<= RC5_CLK_PER_BIT ;
data |= RC5_ONE ;
// Toggle Bit
data <<= RC5_CLK_PER_BIT ;
if (toggle) {
data |= RC5_ONE ;
} else {
data |= RC5_ZERO ;
}
/* address 5bit */
mask = 0x10 ; /* 1 0000 */
while(mask) {
data <<= RC5_CLK_PER_BIT ;
if (address & mask) {
data |= RC5_ONE ;
} else {
data |= RC5_ZERO ;
}
mask >>= 1 ;
}
/* command 6bit */
mask = 0x20 ; /* 10 0000 */
while(mask) {
data <<= RC5_CLK_PER_BIT ;
if (command & mask) {
data |= RC5_ONE ;
} else {
data |= RC5_ZERO ;
}
mask >>= 1 ;
}
print_data(data) ;
ShiftReg_Stop() ;
ShiftReg_WriteRegValue(data) ;
ShiftReg_Enable() ;
}
int main(void)
{
int ir_address = 0 ;
int ir_command = 0 ;
int ir_toggle = 0 ;
init_hardware() ;
splash("IR Remote Emulator") ;
print("Enter toggle(0/1) address(5bit) command(6bit)\n\r") ;
prompt() ;
for(;;)
{
if (get_line()) {
sscanf(str, "%d %d %d", &ir_toggle, &ir_address, &ir_command) ;
snprintf(str, STR_BUF_LEN, "toggle: %d address: %d command: %d\n\r", ir_toggle, ir_address, ir_command) ;
print(str) ;
send_ir(ir_toggle, ir_address, ir_command) ;
prompt() ;
}
}
}
============================
CY8CKIT-042 (receiver)
schematic
pins
main.c
========================
#include "project.h"
#include "stdio.h"
#include "tty_utils.h"
#define IR_ST_IDLE 0
#define IR_ST_START_BIT 1
#define IR_ST_TOGGLE 2
#define IR_ST_ADDRESS 3
#define IR_ST_COMMAND 4
#define IR_ST_DATA_READY 5
#define IR_ADDRESS_WIDTH 5
#define IR_COMMAND_WIDTH 6
volatile int ir_status = IR_ST_IDLE ;
volatile int ir_address_bit = 0 ; /* 5bit */
volatile int ir_command_bit = 0 ; /* 6bit */
volatile int ir_toggle = 0 ;
volatile int ir_address = 0 ;
volatile int ir_command = 0 ;
CY_ISR_PROTO(timer_isr) ;
CY_ISR(ir_isr)
{
isr_ir_ClearPending() ;
if (ir_status == IR_ST_IDLE) {
ir_status = IR_ST_START_BIT ;
isr_ir_Disable() ;
isr_ir_ClearPending() ;
isr_bit_ClearPending() ;
isr_bit_StartEx(timer_isr) ;
bit_timer_ClearInterrupt(bit_timer_INTR_MASK_CC_MATCH) ;
bit_timer_Enable() ;
}
}
CY_ISR(timer_isr)
{
int ir_in ;
bit_timer_ClearInterrupt(bit_timer_INTR_MASK_CC_MATCH) ;
ir_in = IR_input_Read() ;
switch(ir_status) {
case IR_ST_IDLE: // should not come here
break ;
case IR_ST_START_BIT:
if (ir_in == 1) {
ir_status = IR_ST_TOGGLE ;
} else {
ir_status = IR_ST_IDLE ;
}
break ;
case IR_ST_TOGGLE:
ir_toggle = ir_in ;
ir_status = IR_ST_ADDRESS ;
break ;
case IR_ST_ADDRESS:
ir_address <<= 1 ;
ir_address |= ir_in ;
if (++ir_address_bit >= IR_ADDRESS_WIDTH) {
ir_status = IR_ST_COMMAND ;
}
break ;
case IR_ST_COMMAND:
ir_command <<= 1 ;
ir_command |= ir_in ;
if (++ir_command_bit >= IR_COMMAND_WIDTH) {
ir_status = IR_ST_DATA_READY ;
isr_bit_Disable() ;
isr_bit_ClearPending() ;
bit_timer_Stop() ;
}
break ;
case IR_ST_DATA_READY: // should not come here
default: // should not come here
break ;
}
}
void clear_data(void)
{
ir_toggle = 0 ;
ir_address = 0 ;
ir_address_bit = 0 ;
ir_command = 0 ;
ir_command_bit = 0 ;
}
void init_hardware(void)
{
CyGlobalIntEnable; /* Enable global interrupts. */
tty_init() ;
splash("RC5 Test") ;
isr_ir_ClearPending() ;
isr_ir_StartEx(ir_isr) ;
isr_bit_ClearPending() ;
isr_bit_StartEx(timer_isr) ;
bit_timer_Init() ;
}
int main(void)
{
init_hardware() ;
for(;;)
{
if (ir_status == IR_ST_DATA_READY) {
snprintf(str, STR_BUF_LEN, "toggle: %d address %d: command %d\n\r",
ir_toggle, ir_address, ir_command) ;
print(str) ;
clear_data() ;
ir_status = IR_ST_IDLE ;
isr_ir_ClearPending() ;
isr_ir_StartEx(ir_isr) ;
// isr_ir_Enable() ;
}
}
}
========================
Well, let me call it a day 😉
moto
Show Less
Hello everyone,
I am sharing a project that shows a basic example of how we can use the SCB UART block to wake up the PSoC 4 from DeepSleep mode. I have seen multiple examples of using the I2C for waking up PSoC 4 from DeepSleep. The example with UART is a useful one that can be used in various projects.
Kit used: CY8CKIT-145-40XX PSoC 4000S Prototyping Kit (Link)
Softwares used: PSoC Creator 4.4, Tera Term
Documents referred: PSoC 4 Serial Communication Block (SCB) Component Datasheet (Link)
Method:
- Select an empty project
- In the TopDesign add the UART component (Make sure it is SCB version of UART not UDB)
- Mark the option “Enable wakeup from Deep Sleep Mode” in the configuration window option for the UART SCB block component
- I have attached the screenshot of what configuration I have done for the UART
- Also, add a Digital Output pin in the TopDesign which will be used in connecting an LED that will indicate in which mode PSoC 4 is currently in.
- The next step of the project is the Pin Assignment
- Attaching the screenshot of my pin assignment for the project attached. You may change it according to the board used by you
Code:
int main(void)
{
CyGlobalIntEnable;
UART_Start();
for(;;)
{
LED_Write(0); CyDelay(100);
LED_Write(1); CyDelay(100);
LED_Write(0); CyDelay(100);
LED_Write(1); CyDelay(100);
LED_Write(0); CyDelay(100);
LED_Write(1); CyDelay(100);
UART_Sleep(); // required to be used to use the feature of UART to wakeup the device from DeepSleep
CySysPmDeepSleep();
UART_Wakeup();
}
}
Observations:
The program is written such that the LED will remain off in the deep sleep mode but when the device enters the active mode it will blink 3 times after which the device enters the deep sleep mode again.
After configuring any terminal software(I have used Tera Term) you can connect to the PSoC kit with UART. After which entering any character which will make the device Wakeup from the DeepSleep mode. Thus any character entered in the terminal will lead to the LED getting blicked 3 times.
Attaching the project here
Thanks and regards,
Ronak H
Show Less
Hi,
Provided below is custom implementation of the button switch debouncer component (ButtonSw32). The component uses vertical stack counters algorithm to detect button pressed and released events, and can simultaneously process up to 32 switches without loss of performance.
Component can be useful whenever a simple button switch event need to be detected by PSoC with high reliability, such as control switches, panel-mounted momentary buttons, mechanical joysticks, etc. Component is useful when PSoC hardware debouncing is not justified for handling simple switch button, or for a system with limited hardware resources, such as PSoC4.
The component was tested using CY8KIT-059 PSoC5 prototyping kit and CY8KIT-042 PSoC4 Pioneer Board. Several demo projects are provided alongside the Application Note.
Component major features:
Implements vertical counters algorithm.
Detects button pressed and released events.
Detects simultaneously up to 32 buttons.
Does not consume hardware resources.
Attached archive contains component library, component datasheet and several demo projects for PSoC5 and PSoC4. Please read installation instructions in the readme.txt.
The component provided as-is, no liabilities. It is free to use and modify.
regards,
odissey1
=============================================================================
=============================================================================
P.S. Another useful component for HMI can be found here:
Quad Decoder with Button Switch component for rotary shaft encoders
Show Less