Arduino Coding Duty Cycle and DAC output

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?