Display Potentiometer Value on LCD - embedded

I am doing a project using the Mbed OS where I have to use a LCD 1602 to display the value of the potentiometer.
I was able to connect and display "Hello World" on the LCD in my previous project but I don't know how create one where it'll read the potentiometer. I've read through the Arm Mbed web site and still don't know how to create the code.
I'm using a Nucleo board.
The source code for my project is as follows.
#include "mbed.h"
#include "TextLCD.h"
AnalogOut mypot(A0);
TextLCD lcd(D1, D2, D4, D5, D6, D7 ); // rs, rw, e, d4, d5, d6, d7
int main() {
while(1){
for(i=0.0f, i<1.0f , i+=1.0f){
mypot = i
lcd.printf("mypot.read()");
}
}
}

I assume that you want to read the input voltage that is modified by changing the setting of a potentiometer, a kind of variable resistor that has a knob that by twisting divides the incoming voltage into a different output voltage.
It looks like you are using the wrong class, AnalogOut, and should instead be using the class AnalogIn. See https://os.mbed.com/docs/mbed-os/v5.15/apis/analogin.html
Use the AnalogIn API to read an external voltage applied to an analog
input pin. AnalogIn() reads the voltage as a fraction of the system
voltage. The value is a floating point from 0.0(VSS) to 1.0(VCC). For
example, if you have a 3.3V system and the applied voltage is 1.65V,
then AnalogIn() reads 0.5 as the value.
So your program should look something like the following. I don't have your facilities so can't test this but it is in accordance with the Mbed documentation. You will need to make sure you have things wired up to the proper analog pin and that you specify the correct analog pin to be reading from.
#include "mbed.h"
#include "TextLCD.h"
AnalogIn mypot(A0);
TextLCD lcd(D1, D2, D4, D5, D6, D7 ); // rs, rw, e, d4, d5, d6, d7
int main() {
while(1) { // begin infinite loop
// read the voltage level from the analog pin. the value is in
// the range of 0.0 to 1.0 and is interpreted as a percentage from 0% to 100%.
float voltage = mypot.read(); // Read input voltage, a float in the range [0.0, 1.0]
lcd.printf("normalized voltage read is %f\n", voltage);
wait(0.5f); // wait a half second then we poll the voltage again.
}
}
wait() is deprecated but it should work. See https://os.mbed.com/docs/mbed-os/v5.15/apis/wait.html
See as well Working with Text Displays.

Related

Input capture timer 1 atmega 328p to calculate duty cycle

I am new to MP programming and I am working on a project with codevision program, which requires to:
Connect potentiometer at A0.
Generate a PWM signal with an equivalent average DC voltage to the measured value of the voltage of the potentiometer.
The measured voltage from the DAC is displayed on line 1 of lcd (16*2).
Choose a suitable RC circuit to get a pure DC voltage.
Connect the generated PWM signal to the ICP1 and calculate its duty cycle and display it on line 2 off the screen.
So the screen should be like:
Pot1 = 0.000 V
Duty Cycle = ..%
I made the first line but I don't know how to implement timer1 into this requirement.
Also timer 1 has ICRH and ICRL and I am confused which of them should be used.

Structural Verilog) creating a mod-12 counter with 4 D-FF - no outputs from some FFs

I'm trying to make a mod-12 counter in Verilog using 4 D-FFs. I've actually come up with two implementations, one of which works as intended (but is really bad practice IRL), and the other does not work as intended. The following is the ideal(correct) output generated from my "bad" implementation.
And the following is what's generated from the module I'm having trouble with.
Here is the module that generated the top image:
module Mod12Counter(q, clk, rstIn0);
output [3:0] q;
input clk, rstIn0;
DF DF0(q[0], qBar0, qBar0, clk, rst),
DF1(q[1], qBar1, qBar1, qBar0, rst),
DF2(q[2], qBar2, qBar2, qBar1, rst),
DF3(q[3], qBar3, qBar3, qBar2, rst);
and and0(test, q[2], q[3]);
or or0 (rst, rstIn0, test);
endmodule
And here is the module that generated the bottom image:
module Mod12Counter(q, clk, rst);
output [3:0] q;
input clk, rst;
and and0(d1In0, q[1], qBar0),
and1(d1In1, qBar1, q[0]),
and2(d2In0, q[2], qBar1),
and3(d2In1, qBar3, qBar2, q[1], q[0]),
and4(d2In2, q[2], qBar0),
and5(d3In0, q[3], qBar1),
and6(d3In1, q[2], q[1], q[0]),
and7(d3In2, q[3], qBar0);
or or0(d1, d1In0, d1In1),
or1(d2, d2In0, d2In1, d2In2),
or2(d3, d3In0, d3In1, d3In2);
DF DF0(q[0], qBar0, qBar0, clk, rst),
DF1(q[1], qBar1, d1, qBar0, rst),
DF2(q[2], qBar2, d2, qBar1, rst),
DF3(q[3], qBar3, d3, qBar2, rst);
endmodule
What's really weird is these two modules should behave exactly the same way. The only difference is one is just made using my gut feelings and the other one is generated by deriving equations from state tables. From what I know, the bottom module is much more preferable to use IRL.
So far the problem I'm seeing is q[2] and q[3] don't get triggered at all in the bottom module. I've tried using BUS assignment as you see now and I've also tried not using BUS assignment.
I've spent MANY hours on this, and I would really appreciate it if you could help me debug the module, point at the right direction, or tell me a better place to go for things like this.
If q[2] is never going high, the first thing you should look at is to understand why the input to DF2 is not ever going high at the point when the clock rises.
Looking at the inputs to see what drives d2, I see these three lines:
and2(d2In0, q[2], qBar1),
and3(d2In1, qBar3, qBar2, q[1], q[0]),
and4(d2In2, q[2], qBar0),
Obviously and2 and and4 cannot help you here, because they require q[2] to be true in order to be true, so we can throw those out, leaving just these lines to look at:
and3(d2In1, qBar3, qBar2, q[1], q[0]),
or1(d2, d2In0, d2In1, d2In2),
DF2(q[2], qBar2, d2, qBar1, rst),
d2In1 should be high when q is equal to 0011, which then means that d2 will be high at the same time. However you are triggering the clock to DF2 on the rising edge of qBar1, which means that at whenever qBar1 goes high, q[1] is going low, thus causing d2In1 to go low as well. So you have a race condition where the input to the flip flop is falling at the same time the clock edge is rising, which is not good!
Instead of clocking your flip flops on outputs of flip flops (which can give you nasty race conditions), you should let all your flip flops be based on just a single clock, and generate your next state based on the previous value of the flip flops.
Alternatively, here is a very simple solution (you don't always have to design the gates yourself!):
reg [3:0] q;
always #(posedge clk) begin
q <= (q == 4'd11 || rst) ? 0 : q + 1;
end

What is consuming power with PIC18?

I have a very simple code that print out something to the terminal then goes directly to sleep.
For some reason the device is consuming more current during sleep mode. It is drawing 0.24 mA but I know it should be less than that. Without sleep it is consuming 4.32 mA. I've ran the most basic software I can and must be missing something.
Please what are some of the factors that effect power consumption? I really need to lower power consumption but I don't know what's causing it be that high. Here is the Datasheet for your own convenience.
/*
File: main.c
Date: 2011-SEP-4
Target: PIC18F87J11
IDE: MPLAB 8.76
Compiler: C18 3.40
*/
#include <p18cxxx.h>
#include <usart.h>
#pragma config FOSC = HSPLL, WDTEN = OFF, WDTPS = 4096, XINST = OFF
#define FOSC (4000000UL)
#define FCYC (FOSC/4UL)
#define BAUD 9600UL
#define SPBRG_INIT (FOSC/(16UL*BAUD) - 1)
void main(void)
{
/* set FOSC clock to 4MHZ */
OSCCON = 0x70;
/* turn off 4x PLL */
OSCTUNE = 0x00;
/* make all ADC inputs digital I/O */
ANCON0 = 0xFF;
ANCON1 = 0xFF;
/* test the simulator UART interface */
Open1USART(USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH, SPBRG_INIT);
putrs1USART("PIC MICROCONTROLLERS\r\n");
Close1USART();
/* sleep forever */
Sleep();
}
Thanks in advance!
Update 1: I noticed adding the following code decreased it to 0.04 mA
TRISE = 0;
PORTE = 0x0C;
And If I was to change PORTE to the following, it increased to 0.16 mA.
PORTE = 0x00;
But I don't really understand what all of that means ... or how the power consumption went down. I have to be missing something in the code but I don't know what it is.
Update 2: This code gives me unstable current consumption. Sometimes 2.7 mA other times 0.01 mA. I suspect the problem with WDTCONbits.REGSLP = 1;
Download Code
Current consumption nicely went down from 0.24 mA to 0.04 mA when OP change settings on port outputs.
This is expected in typical designs, the outputs control various circuitry. Example: An output, by driving high, may turn on an LED(1), taking an additional 0.20 mA. In another design, an output, by driving low, may turn on an LED. In a 3rd design, not driving may turn on an LED.
OP needs to consult the schematic or designer to determine what settings result in low power. Further, certain combinations may/may not be allowed during low power mode.
Lastly, the sequence of lowering power, disabling, etc. on the various design elements may be important. The sequence to to shut things down is usually reversed in bringing them back on-line.
#Chris Stratton has good ideas in the posted comment.
(1) A low powered LED.

How to get UART to work in PIC32 with correct clock frequency and baud rate?

I am working on UART with pic32mx5xx. All I need is to send a message from pic to terminal (Putty), but it is not working as I would get invalid characters appearing. The baud rate is set to 19200, how do I calculate the clock frequency?
Is it true that the clock frequency of the UART is 16 times the baud rate. If I do the math the clock frequency should be 307200, but this is doesn't seem right.
Can someone help me understand how baud rate and clock frequency relate to each other ? Also how to calculate both?
Thanks!
The baud rate generator has a free-running 16-bit timer. To get the desired baud rate, you must configure its period register UxBRG and prescaler BRGH.
When BRGH is set to 0 (default), the timer is incremented every 16th cycle of peripheral bus clock.
When BRGH is 1, the timer increments every 4th cycle.
It is usually better to set BRGH to 1 to get a smaller baud rate error, as long as the UxBRG value doesn't grow too large to fit into the 16-bit register (on slower baud rates).
The value in the period register UxBRG determines the duration of one pulse on the data line in baud rate generator's timer increments.
See the formulas in section 21.3 - UART Baud Rate Generator in the reference manual to learn how to calculate a proper value for UxBRG.
To compute the period of the 16-bit baud rate generator timer to achieve the desired baud rate:
When BRGH = 0:
UxBRG = FPB / (16 * BAUDRATE) - 1
When BRGH = 1:
UxBRG = FPB / (4 * BAUDRATE) - 1
Where FPB is the peripheral bus clock frequency.
For example, if FPB = 20 MHz and BRGH = 1 and the desired baud rate 19200, you would calculate:
UxBRG = 20000000 / (4 * 19200) - 1
= 259
If you are using some of the latest development libraries and code examples from Microchip you may find that there are already UART methods in the libraries that will set up the PIC for your needs. If you dig deep into the new compiler directory structures you will find help files in the microsoft format (no fear, if you are on a Unix type computer there are Unix utilities that read these types of files.). There you can drill down into the help to find the documentation of various ready made methods you can call from your program to configure the PIC's hardware. Buyer Beware, the code is not that mature. For instance I was working on a PIC project that needed to sample two analog signals. The PIC hardware A/D converter was very complex. But it was clear the ready made code only covered about 10% of that PIC's abilities.
-good luck

PIC18f45k22 serial framing error with 64Mhz clock

I'm trying to transmit serial over the pic18f45k22 eusart peripheral. The messages get sent exactly as expected when the clock is running at 16Mhz, but if I set the PLL to on (so that the the oscillator runs at 64Mhz), I get a framing error.
I have changed the SPBRG registers to account for the new clock frequencey, and tried changing the baudrate generator to both 16 and 8 bit modes, but with no joy.
Current code:
OSCCONbits.IRCF = 0b111; //change Fosc to 16Mhz
OSCTUNEbits.PLLEN = 1; //enable PLL to multiply Fosc by 4
/*Set baud rates and related registers*/
/*For BRG16 = 1 and BRGH = 1, Baud rate = Fosc/(4([SPBRG:SPBRGH]+1)) */
SPBRGH1 = 0; //Set Baud rate control regs to 34 to give baudrate of 115.2k
SPBRG1 = 138;
BAUDCON1bits.BRG16 = 1; //16 bit mode (baudrate generator)
TXSTAbits.BRGH = 1; //Set high speed baud rate
Thanks in advance,
Huggzorx
I'm not familiar with that specific chip but in general, this is what I look at when my UART isn't behaving.
1) Can your clock be divided down to the baud rate with little enough error. Assuming that your baud rate formula in the comments is correct, I think you're okay there:
Baud rate = 16 MHz / (4*(34 + 1)) = 114286 (0.8% error)
Baud rate = 64 MHz / (4*(138 + 1)) = 115107 (0.08% error)
2) Make sure your chip is producing the baud rate you think it should be producing. Some PLLs are really picky about how you turn them on. It's also easy to mis-configure a peripheral. I find that an oscilloscope is your best bet to diagnose this type of problem. If you have access to one, scope the PIC's transmit pin and check that your bit width is 8.68us (1/115200).
If it's 4 times that size (34.72us), then your PLL didn't lock. If it's just a bit off, then the formula might be wrong.
It's not much but hopefully it gets you going in the right direction.