I have an issue where I am multiplying a mapped value and am getting a 9 digit number when I am multiplying 100 x 1000
before setup:
unsigned long oldfreq = 1000;
unsigned long freq = 1000;
In loop:
int medlowHz = analogRead(hz3Pin);
medlowHz = map(medlowHz,0,1023,0,100);
//Serial.print ("mapped hz3 = ");
//Serial.print (medlowHz);
freq = (freq + (medlowHz * 100));
hz3Pin is a analog pin.
It works if (medlowHz * 249) buy not *350
If I have (medlowHz * 1000)
I get on the serial print output
freq = 4294936224
????
The input to the analog pin is a variable resister ("pot") and it's value determines frequency of a dds module. The freq =(freq + (medlowHz * 100)); line takes the value of freq and adds the sum of medlow * 100 to it.
before any of the analog reads is done, freq = 0;
then each input read, mapped, multiplied as needed then added to the current value of freq. This is because I have several knobs one for each "decade" of value such as x10, x100, x1000 to build up the user variable frequency value to drive a dds module
(I know that a digital input can be used but I wanted an analog input and look to this old school looking waveform generator).
Post ALL your code.
You are multiplying 16 bit integers and the result overflowing.
As requested the full code. It is for dds waveform generater.
/*
AD9833 Waveform Module vwlowen.co.uk
*/
#include <SPI.h>
const int SINE = 0x2000; // Define AD9833's waveform register value.
const int SQUARE = 0x2028; // When we update the frequency, we need to
const int TRIANGLE = 0x2002; // define the waveform when we end writing.
int wave = 0;
int waveType = SINE;
int wavePin = 2;
int oldwaveType = SINE; // used to determine if waveType switch has changed
const int sinePin = 6; // waveform selecter switch input
const int triPin = 7;
const int squarePin = 8;
const int hz1Pin = 0; // analog dial input pins
const int hz2Pin = 1;
const int hz3Pin = 2;
const int hz4Pin = 3;
const float refFreq = 25000000.0; // On-board crystal reference frequency
const int FSYNC = 10; // Standard SPI pins for the AD9833 waveform generator.
const int CLK = 13; // CLK and DATA pins are shared with the TFT display.
const int DATA = 11;
const int CS = 9;
// digital pot values for differant wave forms to maintain constant output level
const int TRPOT = 254;
const int SQPOT = 29;
const int SIPOT = 254;
int potMode = SIPOT; // potmode for determining digipot setting
int potVal = 210;
unsigned long oldfreq = 1000;
unsigned long freq = 1000;
; // Set initial frequency.
void setup() {
Serial.begin(9600); //for debugging output to serial terminal
pinMode (CS, OUTPUT);
pinMode (sinePin, INPUT); // sets up ddigital inputs for wave type switch.
digitalWrite (sinePin, HIGH);
pinMode (triPin, INPUT);
digitalWrite (triPin, HIGH);
pinMode (squarePin, INPUT);
digitalWrite (squarePin, HIGH);
// Can't set SPI MODE here because the display and the AD9833 use different MODES.
SPI.begin();
AD9833reset(); // Reset AD9833 module after power-up.
delay(50);
AD9833setFrequency(freq, waveType); // Set the frequency and wave type
}
void loop() {
Serial.print("loop start" );
if (digitalRead(triPin) == LOW) // read waveMode switch pins and set waveMode values
{waveType = TRIANGLE;
}
else if (digitalRead(squarePin) == LOW)
{waveType = SQUARE;
}
else if (digitalRead(sinePin) == LOW)
{waveType = SINE;
}
if (waveType == oldwaveType)
{
// Serial.print("no wave change" );
}
freq = 0;
int bottomHz = analogRead(hz1Pin);
bottomHz = map(bottomHz,0,1023,0,100);
//Serial.print ("mapped hz1 = ");
//Serial.print (bottomHz);
freq = (bottomHz);
int lowHz = analogRead(hz2Pin);
lowHz = map(lowHz,0,1023,0,100);
//Serial.print ("mapped hz2 = ");
//Serial.print (lowHz);
freq = (freq + (lowHz * 10));
int medlowHz = analogRead(hz3Pin);
medlowHz = map(medlowHz,0,1023,0,100);
//Serial.print ("mapped hz3 = ");
//Serial.print (medlowHz);
freq = (freq + (medlowHz * 100));
int medhiHz = analogRead(hz3Pin);
medhiHz = map(medhiHz,0,1023,0,100);
//Serial.print ("mapped hz3 = ");
//Serial.print (medhiHz);
freq = (freq + (medhiHz * 1000));
if (freq != oldfreq) // if waveType has changed then upload settings to ad9833
{
Serial.print("delay" );
delay(1000);
Serial.print ("freq = ");
Serial.print (freq);
delay(1000);
Serial.print("write to ad9833" );
AD9833setFrequency(freq, waveType); // Set the frequency and wave type
}
if (waveType != oldwaveType) // if waveType has changed then upload settings to ad9833
{
Serial.print("delay" );
delay(10);
Serial.print("write to ad9833" );
AD9833setFrequency(freq, waveType); // Set the frequency and wave type
}
oldwaveType = waveType;
oldfreq = freq;
Serial.println("loop end" );
}
// AD9833 documentation advises a 'Reset' on first applying power.
void AD9833reset() {
WriteRegister(0x100); // Write '1' to AD9833 Control register bit D8.
delay(10);
}
// Set the frequency and waveform registers in the AD9833.
void AD9833setFrequency(long frequency, int Waveform) {
long FreqWord = (frequency * pow(2, 28)) / refFreq;
int MSB = (int)((FreqWord & 0xFFFC000) >> 14); //Only lower 14 bits are used for data
int LSB = (int)(FreqWord & 0x3FFF);
//Set control bits 15 ande 14 to 0 and 1, respectively, for frequency register 0
LSB |= 0x4000;
MSB |= 0x4000;
WriteRegister(0x2100);
WriteRegister(LSB); // Write lower 16 bits to AD9833 registers
WriteRegister(MSB); // Write upper 16 bits to AD9833 registers.
WriteRegister(0xC000); // Phase register
WriteRegister(Waveform); // Exit & Reset to SINE, SQUARE or TRIANGLE
}
void WriteRegister(int dat) {
// Display and AD9833 use different SPI MODES so it has to be set for the AD9833 here.
SPI.setDataMode(SPI_MODE2);
digitalWrite(FSYNC, LOW); // Set FSYNC low before writing to AD9833 registers
delayMicroseconds(10); // Give AD9833 time to get ready to receive data.
SPI.transfer(highByte(dat)); // Each AD9833 register is 32 bits wide and each 16
SPI.transfer(lowByte(dat)); // bits has to be transferred as 2 x 8-bit bytes.
digitalWrite(FSYNC, HIGH); //Write done. Set FSYNC high
digipot();
}
void MCP41010Write(byte value)
{
// Note that the integer vale passed to this subroutine
// is cast to a byte
digitalWrite(CS,LOW);
delayMicroseconds(10);
SPI.transfer(B00010001); // This tells the chip to set the pot
SPI.transfer(value); // This tells it the pot position
delay (50);
digitalWrite(CS,HIGH);
}
void digipot ()
{
// Serial.print("waveType = " );
// Serial.println(waveType);
if (waveType == SINE)
{
(potVal = (SIPOT));
}
if (waveType == TRIANGLE)
{
(potVal = (TRPOT));
}
if (waveType == SQUARE)
{
(potVal = (SQPOT));
}
// Serial.println("potVal = " );
// Serial.println(potVal);
if (waveType != oldwaveType)
{
Serial.print("delay" );
delay(10);
Serial.print("write to MCP41010" );
MCP41010Write (potVal);
}
}
Thank you for posting properly.
Integer operations default to 16 bits. Suppose "medlowHz" is 1000, and you multiply it by 100. Is the result more than 32,767?
One way to fix it:
freq = freq + medlowHz * 100UL;
Another way:
freq = freq + (unsigned long)medlowHz * 100;
I removed the useless parentheses.
Thank you very much.
I used your second line and can now dial in up to 111khz.
Hopefully this will also work when I add the high frequency dial where the frequency number will be something like 5,000,000 (5mhz)