Issues with incrementation and decrementation of negative binary numbers

Hello everyone!

I'm trying to make a cycle with a voltage varying from 0 to 5V, then from 5V to -5V and finally from 5 to 0V.
In order to do this, I'm using a SPI DAC (MAX 5312). I already succeed to get the DAC output voltages between -5 and +5V.

But now I have issues to get the right voltage cycle. Here is my loop code. The two fist loops (to go from 0 to 5 and then from 5 to 0) work.
But there are problems as soon as there are negative numbers. The loop which is supposed to go from 0 to -5, goes from +10V to -5. And the last one which is supposed to go from -5V to 0 goes from -5V to +10V.

I tried to write the numbers in 16 bits binary code as well as in decimal numbers, but the issues are still the same ones.
Moreover, the "transfer" function just transfer the code to the DAC.

void loop() {
  
  int command = 0b0100000000000000; // Command which allows DAC output to be updated
  int data;
  int commandPlusData;
  
  
  //Signal incremented from 0 up to 5V
  for (data=0b0000100000000000; data <0b0000110000000000; data++){
      commandPlusData = command | data;
      transfer(commandPlusData);
      delay(30);
  }
  
  
  // Signal decremented from 5 to 0V
  for (data=3072; data > 2048; data--){ 
      commandPlusData = command | data;
      transfer(commandPlusData);
      delay(30);
  }
  

   // Signal decremented from 0 to -5V
  for (data=2048; data > 512; data--){ 
      commandPlusData = command | data;
      transfer(commandPlusData);
      delay(30);
  }
  
  //Signal incremented from -5V up to 0V
  for (data=0b0000001000000000; data < 0b0000100000000000; data++){ 
      commandPlusData = command | data;
      transfer(commandPlusData);
      delay(30);
  }


}

What voltages are you feeding to Vdd and Vss?

That voltage are you feeding to REF?

If you are using 5V for REF you should be using the constants:
0x400 or 1024 = -5V
0x800 or 2048 = 0V
0xC00 or or 3072 = +5V

If you want more precision, use a 2.5V REF:
0x000 or 0 = -5V
0x800 or 2048 = 0V
0xFFF or or 4095 = +5V minus 1 LSB

Looks like you are using 5V REF. I have converted all your constants to HEX for clarity

  //Signal incremented from 0 up to 5V
  for (data=0x800; data < 0xC00; data++){
   
  // Signal decremented from 5 to 0V
  for (data=0xC00; data > 0x800; data--){   

   // Signal decremented from 0 to -5V
  for (data=0x800; data > 0x200; data--) {   // That 0x200 should be 0x400
   
  //Signal incremented from -5V up to 0V
  for (data=0x200; data < 0x800; data++){    // That 0x200 should be 0x400

Those 512 values should produce an output of -7.5V instead of the desired -5V.

You can go from +5 to -5 directly:

  // Signal decremented from +5V to -5V
  for (data=0xC00; data > 0x400; data--) {

If you don't mind starting at +5V you can do it all in two loops:

  // Signal decremented from +5V to -5V
  for (data=0xC00; data => 0x400; data--) {  

  // Signal incremented from -5V to +5V
  for (data=0x400; data <= 0xC00; data++) {

Thank you for your answer!

Vdd and Vss are respectively connected to +15V and -15V.

Yes I'm using a 5V REF, but I can't use any power supply exept the Arduino Power, that's why I'm using the 5V Arduino power.

At the beginning I also thought that I was supposed to get -5V with the constant 1024. But it didn't work. The weird thing is I get -5V when I send 512 to the DAC, -7,5V when I send 256 and also -2,5V when I send 768.
So when I want to send the constant 1024 or 0x400 as you said, the voltage on the DAC output is almost 0V.

I tried to change the 0x200 to 0x400 anyway, and now the voltage loop goes from 0 to 5V, then 5V to 0V, then it jumps to +10V to 0V, and finally it goes from 0V to 10V.

The number format (hex,bin,dec,oct) as you write it it your code makes no difference to the way the number is represented inside the program. Allowing different formats is done because sometimes it is easier to write the number in octal than in decimal (for example).

Mark

Aurelied:
Vdd and Vss are respectively connected to +15V and -15V.

I tried to change the 0x200 to 0x400 anyway, and now the voltage loop goes from 0 to 5V, then 5V to 0V, then it jumps to +10V to 0V, and finally it goes from 0V to 10V.

I know nothing about that DAC, but have you thought that the +10V you're getting may be your +15V supply -5V?

To get more accuracy you could use the 3.3V output of the Arduino for REF. That would give an output range from -6.6V to +6.6V. The 0V value would still be 0x800 and the voltages would be +/- 0x60F (1,551) or 0x1F1 for -5V and 0xE0F for +5V. That would be 3102 steps between -5 and -5 instead of 2048.

Have you got SGND connected to AGND? Are you measuring your output relative to AGND/SGND?

johnwasser:
Have you got SGND connected to AGND? Are you measuring your output relative to AGND/SGND?

I connected all the grounds SGND, AGND, DGND, the Arduino ground and the -/+15V power supply ground all together. And I'm measuring my output relative to one of these grounds.

johnwasser:
To get more accuracy you could use the 3.3V output of the Arduino for REF.

As you suggested, I even used a 2,5V REF by using a voltage divider with the 5V output of the Arduino. But the issue is still the same : at first it's fine, the voltage goes from 0 to 5V, then decreases from 5V to 0V, but then jumps to 5V again, decreases to -5V and increases to 5V. Here is my code.

void loop() {
  
  int command = 0b0100000000000000; // Command which allows DAC output to be updated
  int data;
  int commandPlusData;
  
 //Signal incremented from 0 up to 5V
  for (data=0x800; data < 0xFFF; data++){
         commandPlusData = command | data;
      transfer(commandPlusData);
      delay(15);
  }
  
  // Signal decremented from 5 to -5V
 for (data=0xFFF; data > 0x000; data--){   
      commandPlusData = command | data;
      transfer(commandPlusData);
      delay(15);
  }
  
  //Signal incremented from -5V up to 0V
  for (data=0x000; data < 0x800; data++){   
       commandPlusData = command | data;
      transfer(commandPlusData);
      delay(15);
  }

}

Henry_Best:
I know nothing about that DAC, but have you thought that the +10V you're getting may be your +15V supply -5V?

I don't really get what you mean, why would the DAC power supply affect the output ? I rather tought that the +10V I got was related to the maximum value, which is 2*REF and my REF was +5V.
This might make sense because when I changed my REF to +2,5V, it also jumps to the maximum value, +5V.

Aurelied:
But the issue is still the same : at first it's fine, the voltage goes from 0 to 5V, then decreases from 5V to 0V, but then jumps to 5V again, decreases to -5V and increases to 5V. Here is my code.

I have no clue how that is happening. :frowning:

I think it is time to put in some debug prints to see if it is the code or the DAC that is going wonky. Fortunately that is something I can try on my Arduino here.

The loops are generating the right numbers so there must be something very wonky about the DAC. Are you sure the UNI/BIP pin is tied LOW (=Bipolar)?

Starting first loop: 0 to +5
800
801 802 803 804 805 806 807 808 809 80A 80B 80C 80D 80E 80F 810
811 812 813 814 815 816 817 818 819 81A 81B 81C 81D 81E 81F 820
821 822 823 824 825 826 827 828 829 82A 82B 82C 82D 82E 82F 830
831 832 833 834 835 836 837 838 839 83A 83B 83C 83D 83E 83F 840
.
.
.
F51 F52 F53 F54 F55 F56 F57 F58 F59 F5A F5B F5C F5D F5E F5F F60
F61 F62 F63 F64 F65 F66 F67 F68 F69 F6A F6B F6C F6D F6E F6F F70
F71 F72 F73 F74 F75 F76 F77 F78 F79 F7A F7B F7C F7D F7E F7F F80
F81 F82 F83 F84 F85 F86 F87 F88 F89 F8A F8B F8C F8D F8E F8F F90
F91 F92 F93 F94 F95 F96 F97 F98 F99 F9A F9B F9C F9D F9E F9F FA0
FA1 FA2 FA3 FA4 FA5 FA6 FA7 FA8 FA9 FAA FAB FAC FAD FAE FAF FB0
FB1 FB2 FB3 FB4 FB5 FB6 FB7 FB8 FB9 FBA FBB FBC FBD FBE FBF FC0
FC1 FC2 FC3 FC4 FC5 FC6 FC7 FC8 FC9 FCA FCB FCC FCD FCE FCF FD0
FD1 FD2 FD3 FD4 FD5 FD6 FD7 FD8 FD9 FDA FDB FDC FDD FDE FDF FE0
FE1 FE2 FE3 FE4 FE5 FE6 FE7 FE8 FE9 FEA FEB FEC FED FEE FEF FF0
FF1 FF2 FF3 FF4 FF5 FF6 FF7 FF8 FF9 FFA FFB FFC FFD FFE

Starting second loop: +5 to -5
FFF FFE FFD FFC FFB FFA FF9 FF8 FF7 FF6 FF5 FF4 FF3 FF2 FF1 FF0
FEF FEE FED FEC FEB FEA FE9 FE8 FE7 FE6 FE5 FE4 FE3 FE2 FE1 FE0
FDF FDE FDD FDC FDB FDA FD9 FD8 FD7 FD6 FD5 FD4 FD3 FD2 FD1 FD0
FCF FCE FCD FCC FCB FCA FC9 FC8 FC7 FC6 FC5 FC4 FC3 FC2 FC1 FC0
FBF FBE FBD FBC FBB FBA FB9 FB8 FB7 FB6 FB5 FB4 FB3 FB2 FB1 FB0
FAF FAE FAD FAC FAB FAA FA9 FA8 FA7 FA6 FA5 FA4 FA3 FA2 FA1 FA0
F9F F9E F9D F9C F9B F9A F99 F98 F97 F96 F95 F94 F93 F92 F91 F90
F8F F8E F8D F8C F8B F8A F89 F88 F87 F86 F85 F84 F83 F82 F81 F80
F7F F7E F7D F7C F7B F7A F79 F78 F77 F76 F75 F74 F73 F72 F71 F70
F6F F6E F6D F6C F6B F6A F69 F68 F67 F66 F65 F64 F63 F62 F61 F60
F5F F5E F5D F5C F5B F5A F59 F58 F57 F56 F55 F54 F53 F52 F51 F50
F4F F4E F4D F4C F4B F4A F49 F48 F47 F46 F45 F44 F43 F42 F41 F40
F3F F3E F3D F3C F3B F3A F39 F38 F37 F36 F35 F34 F33 F32 F31 F30
.
.
.
12F 12E 12D 12C 12B 12A 129 128 127 126 125 124 123 122 121 120
11F 11E 11D 11C 11B 11A 119 118 117 116 115 114 113 112 111 110
10F 10E 10D 10C 10B 10A 109 108 107 106 105 104 103 102 101 100
FF FE FD FC FB FA F9 F8 F7 F6 F5 F4 F3 F2 F1 F0
EF EE ED EC EB EA E9 E8 E7 E6 E5 E4 E3 E2 E1 E0
DF DE DD DC DB DA D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
CF CE CD CC CB CA C9 C8 C7 C6 C5 C4 C3 C2 C1 C0
BF BE BD BC BB BA B9 B8 B7 B6 B5 B4 B3 B2 B1 B0
AF AE AD AC AB AA A9 A8 A7 A6 A5 A4 A3 A2 A1 A0
9F 9E 9D 9C 9B 9A 99 98 97 96 95 94 93 92 91 90
8F 8E 8D 8C 8B 8A 89 88 87 86 85 84 83 82 81 80
7F 7E 7D 7C 7B 7A 79 78 77 76 75 74 73 72 71 70
6F 6E 6D 6C 6B 6A 69 68 67 66 65 64 63 62 61 60
5F 5E 5D 5C 5B 5A 59 58 57 56 55 54 53 52 51 50
4F 4E 4D 4C 4B 4A 49 48 47 46 45 44 43 42 41 40
3F 3E 3D 3C 3B 3A 39 38 37 36 35 34 33 32 31 30
2F 2E 2D 2C 2B 2A 29 28 27 26 25 24 23 22 21 20
1F 1E 1D 1C 1B 1A 19 18 17 16 15 14 13 12 11 10
F E D C B A 9 8 7 6 5 4 3 2 1

Starting third loop: -5 to 0
0
1 2 3 4 5 6 7 8 9 A B C D E F 10
11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20
21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30
31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40
41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50
51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60
61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70
71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F 80
81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90
91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F A0
A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0
B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF C0
C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0
.
.
.
771 772 773 774 775 776 777 778 779 77A 77B 77C 77D 77E 77F 780
781 782 783 784 785 786 787 788 789 78A 78B 78C 78D 78E 78F 790
791 792 793 794 795 796 797 798 799 79A 79B 79C 79D 79E 79F 7A0
7A1 7A2 7A3 7A4 7A5 7A6 7A7 7A8 7A9 7AA 7AB 7AC 7AD 7AE 7AF 7B0
7B1 7B2 7B3 7B4 7B5 7B6 7B7 7B8 7B9 7BA 7BB 7BC 7BD 7BE 7BF 7C0
7C1 7C2 7C3 7C4 7C5 7C6 7C7 7C8 7C9 7CA 7CB 7CC 7CD 7CE 7CF 7D0
7D1 7D2 7D3 7D4 7D5 7D6 7D7 7D8 7D9 7DA 7DB 7DC 7DD 7DE 7DF 7E0
7E1 7E2 7E3 7E4 7E5 7E6 7E7 7E8 7E9 7EA 7EB 7EC 7ED 7EE 7EF 7F0
7F1 7F2 7F3 7F4 7F5 7F6 7F7 7F8 7F9 7FA 7FB 7FC 7FD 7FE 7FF

johnwasser:
Are you sure the UNI/BIP pin is tied LOW (=Bipolar)?

Yes this pin is tied low.

johnwasser:
I have no clue how that is happening. :frowning:

I think it is time to put in some debug prints to see if it is the code or the DAC that is going wonky. Fortunately that is something I can try on my Arduino here.

I soldered the DAC to the adapter by myself so maybe I did something wrong, but I checked all the DAC pins and they seemed to be good.
Thank you anyways for trying and for the help.