Hi, currently I have a project car im working on with an Arduino Nano for +-15V and im trying to figure out its duty cycle and DAC voltage output, how exactly would i output this? Analogwrite isnt feasible for this approach and it is connected to a LM339 quad comparater, a 555IC timer and a DAC. Ive tried a bit bang approach but my attempt at it hasnt worked and not 100% sure its the best approach for this type of problem
can you take a step back and explain exactly what you are trying to achieve, regardless of the technical solutions you've looked at?
(do you need an analog value between -15V and +15V, can it be PWM, do you need current / power in this , ...)
Hi apologies, Ill re-explain.
I am trying to implement a way for a user to input a duty cycle percentage that will be inputted through to the arduino for serial write (through a 4 byte package), which will provide the DAC's output voltage.
I am doing this through a PWM signal.
let me rephrase to make sure I got it right:
- you want a PWM signal between -15V and +15V, generated through a DAC.
- The duty cycle of the PWM signal will be variable and received over the UART as a 4 byte payload.
is that right?
Which DAC do you have? can it flip quickly? do you really need a DAC if the only voltage you need is +15V and -15V ?
The output voltage will be received from the UART which is inputted from the serial
byte output1 = 255;
byte output2 = 255;
byte input1 = 0;
byte input2 = 0;
//Declare variables for each byte of the message.
byte startByte = 0;
byte commandByte = 0;
byte dataByte = 0;
byte checkByte = 0;
//Declare variable for calculating the check sum which is used to confirm that the correct bytes were identified as the four message bytes.
byte checkSum = 0;
//Declare a constant for the start byte ensuring that the value is static.
const byte START = 255;
//Declare constants to the port values.
const byte INPUT1 = 0;
const byte INPUT2 = 1;
const byte OUTPUT1 = 2;
const byte OUTPUT2 = 3;
const byte DACPIN1[8] = {9,8,7,6,5,4,3,2};
const byte DACPIN2[8] = {A2,A3,A4,A5,A1,A0,11,10};
const byte SENSOR1 = A6;
const byte SENSOR2 = A7;
void outputToDAC1( byte data ) //loop through Arduino pins connected to DAC and written to correct bit
{
for( int i = 0; i<=7; i++ )
{
digitalWrite( DACPIN1[i] , ((data>>i)&1 ? HIGH : LOW));
}
}
void outputToDAC2( byte data ) //loop through Arduino pins connected to DAC and written to correct bit
{
for( int i = 0; i<=7; i++ )
{
digitalWrite( DACPIN2[i] , ((data>>i)&1 ? HIGH : LOW));
}
}
void initDACs() //loop through Arduino pins connected to DAC and written to correct bit
{
for( int i = 0; i<=7; i++ )
{
pinMode( DACPIN1[i] , OUTPUT);
pinMode( DACPIN2[i] , OUTPUT);
}
}
//Setup initialises pins as inputs or outputs and begins the serial.
void setup()
{
Serial.begin(9600);
initDACs();
}
//Main program setting/reading of ports via serial.
void loop()
{
if (Serial.available() >= 4) // Check full package of four bytes has arrived in the buffer.
{
startByte = Serial.read(); // Get the first available byte from the buffer, assuming that it is the start byte.
if(startByte == START) // Confirm that the first byte was the start byte, otherwise begin again checking the next byte.
{
//Read the remaining three bytes of the package into the respective variables.
commandByte = Serial.read();
dataByte = Serial.read();
checkByte = Serial.read();
checkSum = startByte + commandByte + dataByte; // Calculate the check sum, this is also calculated in visual studio and is sent as he final byte of the package.
if(checkByte == checkSum) //Confirm that the calculated and sent check sum match, if so it is safe to process the data.
{
//Check the command byte to determine which port is being called and respond accordingly.
switch(commandByte)
{
case INPUT1: //In the case of Input 1 the value is read from pin A5 and sent back in the same four byte package format.
{
input1 = digitalRead(SENSOR1);
Serial.write(START); //Send the start byte indicating the start of a package.
Serial.write(commandByte); //Echo the command byte to inform Visual Studio which port value is being sent.
Serial.write(input1); //Send the value read.
int checkSum1 = START + commandByte + input1; //Calculate the check sum.
Serial.write(checkSum1); //Send the check sum.
}
break;
case INPUT2: //Input 2 is the same as Input 1, but read from pin A4
{
input2 = digitalRead(SENSOR2);
Serial.write(START); //Send the start byte indicating the start of a package.
Serial.write(commandByte); //Echo the command byte to inform Visual Studio which port value is being sent.
Serial.write(input2); //Send the value read.
int checkSum2 = START + commandByte + input2; //Calculate the check sum.
Serial.write(checkSum2); //Send the check sum.
}
break;
case OUTPUT1: //For Output 1 the value of the data byte is written to pins in DACPIN1.
{
output1 = dataByte; //The value of the data byte is stored in variable output 1, this step is redundant as the value could be written directly to the port.
outputToDAC1(output1); //However keeping the data in a variable could prove useful if further processing was done on the arduino side.
}
break;
case OUTPUT2: //For Output 1 the value of the data byte is written to pins in DACPIN2.
{
output2 = dataByte;
outputToDAC2(output2);
}
break;
}
}
}
}
}
//Function to reverse the order of the bits.
byte bitFlip(byte value)
{
byte bFlip = 0;
byte j=7;
for (byte i=0; i<8; i++) {
bitWrite(bFlip, i, bitRead(value, j));
j--;
}
return bFlip;
}
This is what my base arduino code is for doing this and the circuit with its models used. The DAC is a DAC0800.
Note: The 18Vs in the image is actually 15V
Your solution looks quite complicated...
Why not use a motor driver?
Like @J-M-L suggested, let's take another step back.
From your schematic it appears that you are trying to achieve bidirectional control of a motor that is grounded at one end so you can't use an H-Bridge. Is that correct?
Is the arduino PWM output so you can replace the PWM generated by the 555 and the DAC?
