Output 0-10V with Arduino (Bit-bang MCP4922 DAC and amplify with TLC272)
Many industrial devices need 0-10 V control signal, to perform some task. For example, a valve actuator will close fully if you send it 0 V and open fully, if you give it 10 V. And everything in between.
How can we send 0-10 V signal from an Arduino? This video is about getting 0-10 V signal out of Arduino with the help of integrated circuits.
// Based on tutorial here: https://circuitdigest.com/article/introduction-to-bit-banging-spi-communication-in-arduino-via-bit-banging
/*
* This example focuses on a specific case of SPI communication,
* where we can use any pin on the Arduino to
* communicate with the peripheral device.
* In this case that's a DAC MCP4922.
*/
// First we define the constants
const int SSPin = 4;
const int SCKPin = 3;
// const int MISOPin = 9; // Not needed for DAC
const int MOSIPin = 2;
// byte slaveData = 0; // Data received by the slave (device),
// but not needed in the MCP4922 example
int x;
void setup() {
pinMode(SSPin, OUTPUT);
pinMode(SCKPin, OUTPUT);
// pinMode(MISOPin, INPUT); Not needed for MCP4922 DAC
pinMode(MOSIPin, OUTPUT);
digitalWrite(SSPin, HIGH); // Just in case, set it "high" initially...
// Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
// Activate DAC
digitalWrite(SSPin, LOW);
x = setDac(1024*4 - 1, 0);
// Deactivate DAC
digitalWrite(SSPin, HIGH);
delay(4);
}
unsigned long setDac(unsigned long value, int channel){ // This function transmits data via bitbanging to the DAC
// byte _receive = 0; We are not receiving anything in the MCP4922 example
unsigned long dacRegister = 0b0011000000000000; // the first nibble (4 bits) of the register is the definition of the: 1st: channel output (A-0, B-1), 2nd: Buffer (check datasheet, default-0), 3rd: Gain (1x-1, 2x-0), 4th: shutdown (active-1. inactive-0), p. 24
// Set the channel
switch(channel){
case 0: // Channel A;
dacRegister &= ~(1 << 15);
break;
case 1: // Channel B;
dacRegister |= (1 << 15);
break;
}
// Write value to the two bytes to be sent to the DAC
unsigned long dacSendBytes = dacRegister | value;
// Start bit-banging
for(int i = 0; i < 16; i++){
digitalWrite(MOSIPin, bitRead(dacSendBytes, 15-i));
delay(2);
digitalWrite(SCKPin, HIGH);
delay(2); // Maybe needed.
digitalWrite(SCKPin, LOW);
}
}