Hello all and happy new year.
I’m new to Arduino, been working on this sketch and need advice at this point. I’ll explain the best I can.
The sketch is for an AM Modulation Meter which is displayed on a Nextion Enhanced display on a Progress Bar with a value range of 0 to 100. In AM modulation there are Positive and Negative peaks. Here we are working with the positive peaks only.
Initially, when the carrier is first present the Arduino sees an incomingCarrierLevel DC signal on pin A3 ranging between 0 and 5 volts.
(A). Waits 1 second and if the incomingCarrierLevel DC signal has not changed value during this 1 second, the modulationRange scaling (0 to 300) must first be calibrated with this value to auto map the incomingCarrierLevel (0 to 1023) to always be 25 (same as 1/12 or ~.083%) within one second.
modulationRange must be calibrated to properly display the upcoming modulation peak values.
For example:
Map the incomingCarrierLevel (0 to 1023) to the modulationRange (0 to 300) and give it the value of 25.
[code]
modulationRange = map ( incomingCarrierLevel, 0, 1023, 0, 300 ); //need to assign value of 25 or .083% of 300, to the modulationRange with a scale ranging from 0 to 300.
At this point modulationRange (0 to 300) should hold the value of 25 (.083% full) which must be mapped and displayed on the modulationMeter range in the Nextion display at 8.3 on the scale of 0 to 100. At this time a red marker (carMarker) must flash at the corresponding position at 8.3 (.083% of the 0 to 100 Nextion Progress Bar scale).
For example:
Map the modulationRange (0 to 300) to the modulationMeter (0 to 100) on the Nextion display.
[code]
modulationMeter = map ( modulationRange, 0, 300, 0, 100 ); //need to assign value of 8.3 or .083% of 100, to the modulationMeter with a scale ranging from 0 to 100.
The mapped scale and value of the modulationRange must be held as reference to properly display the upcoming modulation peak values during this loop. The loop must exit when the modulation stops for one second, at this time loop and auto map the incomingCarrierLevel DC signal on pin A3 again to 25 of the modulationRange (0 to 300), map and display on the modulationMeter on the Nextion display and loop again when the modulation ends and keep repeating this process.
While in the loop, peak modulation values in modulationMeter must be displayed on the Nextion Progress Bar with the scaling ratio set within the loop right after the first second of the incomingCarrierLevel DC signal above (A).
Negative modulation must also be displayed on a second progress bar on the Nextion display. Implementing should be like the above so we will need two meters. For now I’ll like to focus on getting the positive modulation meter running first.
In conclusion, the process seems rather simple, get the carrier value sample for one second, set the scaling factor accordingly and display the modulation.
BTW: If anyone knows how to write to the non-volatile registers of the MCP4461 digital pot, please share the information. I have contacted Microchip and they have not been able to provide a code sample and the few libraries available for the MCP series of DigiPots are very limited with no sample code and with errors. I had to change and tweak the one I’m using to get it to work only on the volatile wipers and use the Nextion EEPROM to save the slider positions and load them at POR, send them to Arduino to send to the DigiPot. MCP4461 library at GitHub. If anyone needs mine, let me know and I’ll post it. I'm sure there is an easier method to accomplish this task and know this code is nowhere near perfect due to my lack of experience with programming, but always been a fan of constructive criticism. Thank you for your time and help in advanced..
=>My code:
#include <MYMCP4461.h> //MCP4461 Digital Potentiometer(DigiPot) library
MYMCP4461 myMCP4461 = MYMCP4461();
int RFInputPin(A3); //RF volt sample input signal
void setup() {
Serial.begin(38400);
myMCP4461.setMCP4461Address(47); //set the I2C address for the DigiPot
myMCP4461.begin(); //Begin Digipot functions
pinMode(A3,INPUT); //Set analog pin 3 as an input
delay(100);
}
void loop() {modulation();} // Other loops omited for simplicity
void modulation(){ //Modulation meter loop
unsigned long currentMill = 0;
int interval = (1000);
int incomingCarrierLevel; //Vlue at pin A3 (RF volt sample, 0 to 1023)
int modulationRange(0); //Holds mapped value of "inputSignal" 0, 1023 mapped to 0, to 100
int car1In(0);
int inputCar1(0);
int carrier1(0);
int car2In(0);
int inputCar2(0);
int carrier2(0);
int mod1In(0);
int inputMod1(0);
int mod1(0);
int mod2In(0);
int inputMod2(0);
int mod2(0);
int j0ValCar;
int j0ValMod;
int j3Val;
int carMarker;
incomingCarrierLevel = analogRead(RFInputPin); //Read DC voltage 0 to 5 volts pin A3
modulationRange=(100./1023.)*incomingCarrierLevel; //Convert/map 1023 scale to 100 scale
if (modulationRange >= 1) { //If detected voltage is greater than 1 continue
car1In = analogRead(RFInputPin); //Assign RFInputPin value to car1In
if(car1In == 0){j0ValCar=0; j0ValMod=0;} //If car1In is 0 make sure j0 carrier and modulation value are 0
inputCar1=(100./1023.)*car1In; //Assign and map car1In value to inputCar1
carrier1 = inputCar1; //Assign value of inputCar1 to carrier1
if(millis() > (currentMill + interval)){ //Wait 1 second to see if the carrier1 value doesn't change
currentMill = millis(); //when compared to the carrier2 value on line 53
car2In = analogRead(RFInputPin); //Assign RFInputPin value to car2In realtime after the delay on line 46 to compare at line 53
inputCar2=(100./1023.)*car2In; //Assign and map car2In value to inputCar2 (independent of car1In)
carrier2 = inputCar2; //Assign value of inputCar2 to carrier2
if (carrier1 == carrier2) { //if after 1 second carrier1 is same value as carrier2 do the below
j0ValCar = map(carrier1, 0, carrier2, 0, 100); //Map Nextion Progress Bar from 0 to the carrier2 value, and map it to j0ValCar at .083% or 8.3 on the 0 to 100 scale on Nextion
j3Val= (carMarker, j0ValCar); //Assign carrier value to flashing carrier marker at the 8.3 mark in the scale of 0 to 100
mod1In = analogRead(RFInputPin); //Get modulation
inputMod1=(100./1023.)*mod1In; //Assign and map mod1In value to inputMod1
mod1 = inputMod1; //Assign value of inputMod1 to mod1
j0ValMod = map(mod1, 0, mod2, 0, 100); //Map mod1 with the scalling factor set on line 54 by carrier value mapped to .083% of the 0 to 100 scale
if(millis() > (currentMill + 100)){ //Count to 100 ms to send carrier value to Nextion within this time range
currentMill = millis();
Serial.print ("j0.val="); //Send the destination to write on Nextion (j0 Progress Bar)
Serial.print (j0ValCar); //Send carrier value to the Nextion display within the 100 milliseconds
Serial.write(0xff); //Required block of 3 ff packets at the end of each transmission to Nextion
Serial.write(0xff);
Serial.write(0xff);
Serial.print ("j3.val="); //Send the destination to write to on Nextion (flashing marker on j3 Progress Bar, superimposed on j0)
Serial.print (j3Val); //Send marker value to the Nextion display within the 100 milliseconds
Serial.write(0xff); //Required block of 3 0xff packets at the end of each transmission to Nextion
Serial.write(0xff);
Serial.write(0xff);
}else{
Serial.print ("j0.val="); //Send the destination to write the modulation values on Nextion (j0 Progress Bar)
Serial.print (j0ValMod); //Send modulation values to the Nextion display.
Serial.write(0xff); //Required block of 3 0xff packets at the end of each transmission to Nextion
Serial.write(0xff);
Serial.write(0xff);
}
}
else if (mod1<1){ //if signal ends, loop and wait for next carrier and start all over
return;}
}
}
}