- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi there, i need to convert a weight into voltage.
i got a scale (KERN PCB) i am using UART to read the info and USBUART to see it on my computer.
My measures are from 0 to 2500 gr - so for the conversion to voltage i want to use PWM with a period of 2500 and Compare value that come from the scale (KERN PCB).
- i got a problem collecting the data and put it in the PWM Compare function.
The data that i get from the scale is an 8 bits ascii characters.
this is my code:
#include "project.h"
#include "stdio.h"
#include <stdlib.h>
#define USBFS_DEVICE (0u)
int main()
{
CyGlobalIntEnable
LCD_Start();
USBUART_Start(USBFS_DEVICE, USBUART_5V_OPERATION);
UART_Start();
PWM_Start();
char8 ch = 0;
for(;;)
{
ch = 0;
ch = UART_GetChar();
if(ch > 0u)
{
USBUART_PutChar(ch);
}
PWM_WriteCompare(ch);
}
}
i tried to debug the and see the value that "ch" is getting (for better understanding how to handle the data) but im getting an error,
- first, is it possible to debug communication?
- second, i connecting 2 cables at the same time to the psoc, i think that the error is due to that.
it will be helpful if someone have an idea how to debug or how to handle the data and put it in the PWM Compare function.
Thank you all
Best Regard
Michael
Solved! Go to Solution.
- Labels:
-
PSoC 5LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Michael-san,
Attached is the version for CY8CKIT-050.
Please connect
P12[6] to TxD of your USB-Serial Adapter
P12[7] to RxD of your USB-Serial Adapter
VSSD to GND of your USB-Serial Adapter
Meantime to see the PWM, I assigned P6[0]
so please connect P6[0] to LED1 (to test)
(1) To test with TeraTerm
Please connect USB-Serial Adapter to TeraTerm (via PC)
At first the program title "uart to pwm" is printed along with its built time.
Then if you type
"1200" the red led (LED1) light about half brightness.
"0" the led turns off
"2500" the led turn of at it full brightness
"0" the led turns off
(2) to connect to the scale (KERN PCB?), connect P12[6], P12[7] and VSSD to KERN PCB.
Then, I hope, we can see the LED's brightness changes according to the scale value.
Now trying to answer your questions...
> in which part of the "get_line()" function the information is derived from the uart?
In the source "tty_utils.c" the data acquisition from UART is done in an ISR (interrupt service routine)
It only pool the received data into rx_buff[] with rx_write_idex increment.
===============
CY_ISR(tty_rx_isr)
{
if (UART_GetRxBufferSize()) {
rx_buf[rx_write_index] = UART_GetByte() ;
rx_write_index = (rx_write_index + 1) % RX_BUF_LEN ;
}
tty_rx_int_ClearPending() ;
}
===============
Note: Following line make the buffer as a ring buffer.
So when rx_write_index reaches to the last part of the buffer,
it continues from 0.
rx_write_index = (rx_write_index + 1) % RX_BUF_LEN ;
> is this "get_line()" function return a Boolean value? (im trying to understand the "if" below).
int get_line(void) in tty_utils.c returns
(1) length of the line received if it is within the length of STR_BUF_LEN
(2) -1 if the line was exceeding STR_BUF_LEN, to stop overflow get_line() terminate the string after the last letter within STR_BUF_LEN
to do this, str[] was defined as char str[STR_BUF_LEN+1].
(3) 0 if the receiving line is still go on.
So following block was
(1) get_line() returns 0 when input is not terminated with EOL, so the followning block is skipped
(2) get_line() returns -1 or the length of received line when a new line Line Feed ('\n') or Carriage Return ('\r') was received after some letters.
Then program enters the block following the if ().
> compare = str2pwm(str) ;
This line convert str, which is the received line to an integer value.
From your TeraTerm log, I assumed that the scale sends something like "1936.79 g".
At first I search '.' and if there is '.' in the str, I replace the letter with (char)0,
this way, the str is now "1936".
Then sscanf(str, "%hd", &value) converts the strings "1936" to an integer 1936.
So compare is assigned the first integer value of the line received.
From the line /* set compare */
(1) Stop PWM before modifying parameter. : PWM_Stop() ;
(2) Reset the count value to 0 or if the count value is larger than compare
it may run long time till the end of the counter : PWM_WriteCounter(0) ;
(3) Set the new compare value : PWM_WriteCompare(compare) ;
(4) Restart PWM by calling PWM_Enable() ;
================
if (get_line()) { // got a line
compare = str2pwm(str) ;
/* set compare */
PWM_Stop() ;
PWM_WriteCounter(0) ;
PWM_WriteCompare(compare) ;
PWM_Enable() ;
}
================
Best Regards,
23-Oct-2019
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
This is my quick hack, taking care of only input part of the uart input.
I used CY8CKIT-059 and UART is only via KitProg.
I cheated using my uart tty sample.
tty_utils a utility sample for CLI type program
get_line() read up to EOL and return char str[] ;
Then I check if it has '.' inside and make that char to NULL so that only integer part will be a valid string.
So uart input something like both
1359.62 g
and
2349
will work (I hope)
main.c
=======================
#include "project.h"
#include "stdio.h"
#include "string.h"
#include "tty_utils.h"
void init_hardware(void)
{
tty_init() ;
PWM_Start() ;
CyGlobalIntEnable; /* Enable global interrupts. */
}
uint16_t str2pwm(char *str)
{
char *ptr ;
uint16_t value = 0 ;
ptr = strchr(str, '.') ; /* find '.' */
if (ptr) {
*ptr = (char) 0 ; /* terminate the string at '.' */
}
sscanf(str, "%hd", &value) ;
return(value) ;
}
int main(void)
{
uint16_t compare ;
init_hardware() ;
splash("uart to pwm") ;
// prompt() ; /* for human input */
for(;;) {
if (get_line()) { // got a line
compare = str2pwm(str) ;
/* set compare */
PWM_Stop() ;
PWM_WriteCounter(0) ;
PWM_WriteCompare(compare) ;
PWM_Enable() ;
}
}
}
=======================
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi moto, thank you very much for the reply!
im using CY8CKIT-050 'CY8C5868AXI-LP035'
- there is a way that i can modify the project that you attached for my kit?
also i tried to use some of your code on my project, but unfortunately my coding skills are not good as yours (yet )
therefore i got confused.
can you please explain me :
- in which part of the "get_line()" function the information is derived from the uart?
- is this "get_line()" function return a Boolean value? (im trying to understand the "if" below).
if (get_line()) { // got a line
compare = str2pwm(str) ;
/* set compare */
PWM_Stop() ;
PWM_WriteCounter(0) ;
PWM_WriteCompare(compare) ;
PWM_Enable() ;
}
- how the information is getting into str ?
int get_line(void)
{
int result = 0 ;
if (rx_read_index != rx_write_index) {
if (is_eol(rx_buf[rx_read_index])) {
str[str_buf_index] = (char)NULL ;
result = str_buf_index ;
str_buf_index = 0 ;
} else {
str[str_buf_index++] = rx_buf[rx_read_index] ;
if (str_buf_index >= STR_BUF_LEN) {
str[STR_BUF_LEN] = (char)NULL ;
str_buf_index = 0 ;
result = -1 ; /* str buf overflow */
}
}
rx_read_index = (rx_read_index + 1) % RX_BUF_LEN ;
}
return( result ) ;
}
- i am sure that most of my confusion is due to the fact that im not familiar with low end coding, do you familiar with a tutorial about it? is it special coding for arm processors?
I hope that its is not a lot of trouble for you,
thank you very much !
Michael
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Michael-san,
Attached is the version for CY8CKIT-050.
Please connect
P12[6] to TxD of your USB-Serial Adapter
P12[7] to RxD of your USB-Serial Adapter
VSSD to GND of your USB-Serial Adapter
Meantime to see the PWM, I assigned P6[0]
so please connect P6[0] to LED1 (to test)
(1) To test with TeraTerm
Please connect USB-Serial Adapter to TeraTerm (via PC)
At first the program title "uart to pwm" is printed along with its built time.
Then if you type
"1200" the red led (LED1) light about half brightness.
"0" the led turns off
"2500" the led turn of at it full brightness
"0" the led turns off
(2) to connect to the scale (KERN PCB?), connect P12[6], P12[7] and VSSD to KERN PCB.
Then, I hope, we can see the LED's brightness changes according to the scale value.
Now trying to answer your questions...
> in which part of the "get_line()" function the information is derived from the uart?
In the source "tty_utils.c" the data acquisition from UART is done in an ISR (interrupt service routine)
It only pool the received data into rx_buff[] with rx_write_idex increment.
===============
CY_ISR(tty_rx_isr)
{
if (UART_GetRxBufferSize()) {
rx_buf[rx_write_index] = UART_GetByte() ;
rx_write_index = (rx_write_index + 1) % RX_BUF_LEN ;
}
tty_rx_int_ClearPending() ;
}
===============
Note: Following line make the buffer as a ring buffer.
So when rx_write_index reaches to the last part of the buffer,
it continues from 0.
rx_write_index = (rx_write_index + 1) % RX_BUF_LEN ;
> is this "get_line()" function return a Boolean value? (im trying to understand the "if" below).
int get_line(void) in tty_utils.c returns
(1) length of the line received if it is within the length of STR_BUF_LEN
(2) -1 if the line was exceeding STR_BUF_LEN, to stop overflow get_line() terminate the string after the last letter within STR_BUF_LEN
to do this, str[] was defined as char str[STR_BUF_LEN+1].
(3) 0 if the receiving line is still go on.
So following block was
(1) get_line() returns 0 when input is not terminated with EOL, so the followning block is skipped
(2) get_line() returns -1 or the length of received line when a new line Line Feed ('\n') or Carriage Return ('\r') was received after some letters.
Then program enters the block following the if ().
> compare = str2pwm(str) ;
This line convert str, which is the received line to an integer value.
From your TeraTerm log, I assumed that the scale sends something like "1936.79 g".
At first I search '.' and if there is '.' in the str, I replace the letter with (char)0,
this way, the str is now "1936".
Then sscanf(str, "%hd", &value) converts the strings "1936" to an integer 1936.
So compare is assigned the first integer value of the line received.
From the line /* set compare */
(1) Stop PWM before modifying parameter. : PWM_Stop() ;
(2) Reset the count value to 0 or if the count value is larger than compare
it may run long time till the end of the counter : PWM_WriteCounter(0) ;
(3) Set the new compare value : PWM_WriteCompare(compare) ;
(4) Restart PWM by calling PWM_Enable() ;
================
if (get_line()) { // got a line
compare = str2pwm(str) ;
/* set compare */
PWM_Stop() ;
PWM_WriteCounter(0) ;
PWM_WriteCompare(compare) ;
PWM_Enable() ;
}
================
Best Regards,
23-Oct-2019
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
wow, thank you very much Motoo !
its work !
also I learned a lot from your code, i really appreciate it!
Best Regards
Michael