Thanks Henrik! I'll try that tonight.
Thanks Henrik! I'll try that tonight.
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
Bookmarks