since I might have to change that constant of 39332, how did you arrive at that value?
since I might have to change that constant of 39332, how did you arrive at that value?
Your formula works, Henrik - not that should come as a surprise. Knowing how you arrived at that constant in the expression would help me me adjust for different resolutions.
Here's the code I used to test Henrik's formula:
Here's the annoying part - no matter how many searches I do here I can't find the syntax to print on the 2nd line of the LCD. With the above the screen just seems to flicker (which also doesn't make sense - with the ADC method here it usually results in a rock-solid value; in other words, it doesn't change until I actually move the wiper arm. I know it's unrelated to the original post, but any ideas?Code:#DEFINE USE_LCD_FOR_DEBUG ; comment out for non-debug use ' *************************************************************** ' Pin Connections ' *************************************************************** ' Vdd -> pin 1 -> +5V ' RC4/Tx -> pin 6 -> EUSART transmit (LCD) ' RA1 -> pin 12 -> trim pot input ' Vss -> pin 14 -> GND DEFINE OSC 16 ; Set oscillator 16Mhz DEFINE HSER_TXSTA 20h ; Set transmit status and control register DEFINE HSER_BAUD 2400 ; Set baud rate ' *************************************************************** ' Device Fuses ' *************************************************************** #CONFIG __config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF __config _CONFIG2, _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF #ENDCONFIG ' *************************************************************** ' Initialization ' *************************************************************** OSCCON = %01111000 ; 16MHz internal osc APFCON0.2 = 0 ; Tx on RC4 for LCD display APFCON0.7 = 0 ; Rx on RC5 BAUDCON.4 = 1 ; Transmit inverted data to the Tx pin ANSELC = 0 ; Digital only for all PortC pins TRISC = 0 ; Make all PORTC pins output TRISA = %00000010 ; Make all pins output except for RA1 (trim pot input) ANSELA = %00000010 ; Analog on PORTA.1 (AN1) only FVRCON = 0 ; Fixed Voltage Reference is disabled ADCON0 = %00000101 ; ADC enabled on AN1 (RA1) only; ADC conversion enabled PAUSEUS 20 ; wait for the analog switch 'glitch' to die down ADCON1 = %00110000 ; Left-justified results in 8-bits; Frc as timer #IFDEF USE_LCD_FOR_DEBUG LCD_INST CON 254 ' instruction LCD_CLR CON 1 ' Clear screen LCD_L1 CON 128 ' LCD line 1 LCD_L2 CON 192 ' LCD line 2 #ENDIF MotorDuty VAR BYTE ; Actual duty cycle for motor ADCInVal VAR BYTE ; stores ADCIN result read from trim pot MinDuty CON 100 ; Minimum speed to rotate motor for this application Main: gosub Do_ADC pause 100 GOSUB Map_ADC_Val_to_PWM_Duty GOTO Main Do_ADC: PAUSEUS 50 ' Wait for A/D channel acquisition time ADCON0.1 = 1 ' Start conversion WHILE ADCON0.1 = 1 ' Wait for it to complete WEND ADCInVal = ADRESH return Map_ADC_Val_to_PWM_Duty: ' Arduino Map function to emulate: ' =============================== ' map(value, fromLow, fromHigh, toLow, toHigh) ' long map(long x, long in_min, long in_max, long out_min, long out_max) ' { ' return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; ' } ' MotorDuty = (ADCInVal - 0) * (MaxDuty - MinDuty)/(MaxADCVal - 0) + MinDuty MotorDuty = (ADCInVal ** 39322) + MinDuty ' Same as 100 + ADCInValue * 0.600006 but likely faster than 100+ADCInValue*6/10 #IFDEF USE_LCD_FOR_DEBUG HSEROUT [LCD_INST, LCD_CLR] pause 5 ' HSEROUT ["ADCInVal=", DEC ADCInVal, " ", 13, 10] ; Send text followed by carriage return and linefeed HSEROUT ["ADCInVal=", DEC ADCInVal, " ", 13, 10, "MotorDuty=", DEC MotorDuty] ' pause 5 ' HSEROUT ["MotorDuty=", DEC MotorDuty, " "] ; Send text followed by carriage return and linefeed #ENDIF RETURN
Hi,
Think of the ** operator as multiplying by units of 1/65536. 0.6*65536=39322.
As for printing to second line of the LCD you're obviously using some sort of serial interface display(?) which I know nothing about but if I'd make a guess based on your defined constants you'd do something like/Henrik.Code:HSEROUT[LCD_INST, LCD_L2, "2d Line"]
Thanks Henrik. You'd think I would have noticed that constant. Changing the HSEROUT to this:
I can now see the 2nd line, but it's not starting at the first character position and there's a weird character there before 'MotorDuty'. It might be related to the spaces after the first line, but I'm not sure. Also, the first line seems to be refreshing/fluttering even when I'm not moving the trim pot. I have to admit, I use my serial LCD so infrequently that I'm a noobie where it comes to this.Code:#DEFINE USE_LCD_FOR_DEBUG ; comment out for non-debug use ' *************************************************************** ' Pin Connections ' *************************************************************** ' Vdd -> pin 1 -> +5V ' RC4/Tx -> pin 6 -> EUSART transmit (LCD) ' RA1 -> pin 12 -> trim pot input ' Vss -> pin 14 -> GND DEFINE OSC 16 ; Set oscillator 16Mhz DEFINE HSER_TXSTA 20h ; Set transmit status and control register DEFINE HSER_BAUD 2400 ; Set baud rate ' *************************************************************** ' Device Fuses ' *************************************************************** #CONFIG __config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF __config _CONFIG2, _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF #ENDCONFIG ' *************************************************************** ' Initialization ' *************************************************************** OSCCON = %01111000 ; 16MHz internal osc APFCON0.2 = 0 ; Tx on RC4 for LCD display APFCON0.7 = 0 ; Rx on RC5 BAUDCON.4 = 1 ; Transmit inverted data to the Tx pin ANSELC = 0 ; Digital only for all PortC pins TRISC = 0 ; Make all PORTC pins output TRISA = %00000010 ; Make all pins output except for RA1 (trim pot input) ANSELA = %00000010 ; Analog on PORTA.1 (AN1) only FVRCON = 0 ; Fixed Voltage Reference is disabled ADCON0 = %00000101 ; ADC enabled on AN1 (RA1) only; ADC conversion enabled PAUSEUS 20 ; wait for the analog switch 'glitch' to die down ADCON1 = %00110000 ; Left-justified results in 8-bits; Frc as timer #IFDEF USE_LCD_FOR_DEBUG LCD_INST CON 254 ' instruction LCD_CLR CON 1 ' Clear screen LCD_L1 CON 128 ' LCD line 1 LCD_L2 CON 192 ' LCD line 2 #ENDIF MotorDuty VAR BYTE ; Actual duty cycle for motor ADCInVal VAR BYTE ; stores ADCIN result read from trim pot MinDuty CON 100 ; Minimum speed to rotate motor for this application Main: gosub Do_ADC pause 100 GOSUB Map_ADC_Val_to_PWM_Duty GOTO Main Do_ADC: PAUSEUS 50 ' Wait for A/D channel acquisition time ADCON0.1 = 1 ' Start conversion WHILE ADCON0.1 = 1 ' Wait for it to complete WEND ADCInVal = ADRESH return Map_ADC_Val_to_PWM_Duty: ' Arduino Map function to emulate: ' =============================== ' map(value, fromLow, fromHigh, toLow, toHigh) ' long map(long x, long in_min, long in_max, long out_min, long out_max) ' { ' return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; ' } ' MotorDuty = (ADCInVal - 0) * (MaxDuty - MinDuty)/(MaxADCVal - 0) + MinDuty MotorDuty = (ADCInVal ** 39322) + MinDuty ' Same as 100 + ADCInValue * 0.600006 but likely faster than 100+ADCInValue*6/10 #IFDEF USE_LCD_FOR_DEBUG HSEROUT [LCD_INST, LCD_CLR] pause 5 ' HSEROUT ["ADCInVal=", DEC ADCInVal, " ", 13, 10] ; Send text followed by carriage return and linefeed HSEROUT ["ADCInVal=", DEC ADCInVal, " ", LCD_L2, "MotorDuty=", DEC MotorDuty, " ", 13, 10] ' pause 5 ' HSEROUT ["MotorDuty=", DEC MotorDuty, " "] ; Send text followed by carriage return and linefeed #ENDIF RETURN
Here's a video of what the screen looks like.
try
HSEROUT ["ADCInVal=", DEC ADCInVal, " ", LCD_INST,LCD_L2, "MotorDuty=", DEC MotorDuty, " ",13,10]
I used the HSEROUT line exactly as above and when I turn on the power:
Then, as I turn the trim pot wiper:
The serial LCD is 2400 baud by default and that's what I have set in code, but maybe there's some timing issues?
If I'm using a PIC16F1825 how do I know whether to use the USART or EUSART settings from Mister E's PIC Multi-Calc application? This is what I have set currently:
I see that Mister E's app doesn't use DEFINE HSER_BAUD. For USART I get:Code:DEFINE OSC 16 ; Set oscillator 16Mhz DEFINE HSER_TXSTA 20h ; Set transmit status and control register DEFINE HSER_BAUD 2400 ; Set baud rate DEFINE HSER_CLROERR 1 OSCCON = %01111000 ; 16MHz internal osc PAUSE 100 APFCON0.2 = 0 ; Tx on RC4 for LCD display APFCON0.7 = 0 ; Rx on RC5 BAUDCON.4 = 1 ; Transmit inverted data to the Tx pin
For EUSART:Code:DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0 DEFINE HSER_SPBRG 103 ' 2400 Baud @ 16MHz, 0.17% DEFINE HSER_CLROERR 1 ' Clear overflow automatically
Which should I use? And should I continue to use DEFINE HSER_BAUD which I think I got from this board a ling time ago?Code:DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1 DEFINE HSER_CLROERR 1 ' Clear overflow automatically DEFINE HSER_SPBRG 130 ' 2400 Baud @ 16MHz, 0.0% SPBRGH = 6 BAUDCON.3 = 1 ' Enable 16 bit baudrate generator
either setting will work the 0% error eusart option is probably best ,
if you set the baudrate regs manually ie
DEFINE HSER_SPBRG 130 ' 2400 Baud @ 16MHz, 0.0%/SPBRGH = 6
or
DEFINE HSER_SPBRG 103 ' 2400 Baud @ 16MHz, 0.17%
then DEFINE HSER_BAUD should not be used ,it may cause your setting to be overwritten
ps
baudrate error is not your display problem, you need to find out
1. how to initialise your display and how long it takes to happen
2. how to send control codes to the display ( seems $fe is not correct)
do you have any docs for the display / or a model no ?
Bookmarks