The MicroChip Digipots (4100 series) Not Responding to My Teensy 3.2

Status
Not open for further replies.

DaveC284

Member
Hi,

I wrote the attached code for the Nano, and had the Nano controlling the MCP41xx and 42xx series digipots just fine. It worked well and I kept expanding and adding features until I ran out of programming space. Switched to the Teensy3.2, then had lots of space, which allowed me to add a user interface for controlling the digipots. I thought I successfully tested the control of the digipots using the Teensy at some point, but in my latest test, nothing was happening. So I uploaded and re-tested using the pre-User Interface version (attached). It's the same Nano code, only recompiled it for the Teensy.

I have confirmed that the digipots are receiving all 3 signals properly: 1) Chip select via the demux, 2) 16 pulses of clk, and 3)the concurrent 16 pulses of data. SPI Data is only transmitted when there is a change - not continuously. I have one dual-channel and several single channel digipots and none of them are responding. They are all receiving all 3 signals.

I attached the .zip file of the code. I use 4 address pins to a 4-to-16 line demux chip (74xx154) to address several other SPI devices. Also attached is the 2 of 3 pages of project schematic.

It's possible that I may not have configured the digipots correctly. It worked for the Nano. Why not the Teensy3.2?

Any suggestions?

Thanks,
Dave
 

Attachments

  • Teensy32_Demo_Pre-UI_DigiPot_EEPROM_PWM.zip
    14.6 KB · Views: 28
  • Schematic RevB - Audio Processing (Sh1).pdf
    274.3 KB · Views: 32
  • Schematic RevB - Teensy 3.2 MCU & Pwr Supply(Sh3).pdf
    174.3 KB · Views: 32
Hi Paul,

Thanks for the suggestion. I should have mentioned that I've tried that too, and it didn't make any difference.

If you think of anything else, please let me know. As best I can tell, everything should be working. I was hoping it would be something silly I had done to mess things up.

Thanks,
Dave
 
Have you checked if your signals are still high enough? The Teensy3.2 may be 5V tolerant, but it doesn't output 5V like the arduino nano. It is still 3.3V and it is trying to control 5V ICs with it.
Might be that they fall (just) short of the Input-HIGH Threshold.

I'd try to look through the code, but i would have to be honest in saying that i Can't see the forest through the trees.
Splitting code into files for better oversight is good, but the idea is like say all digipot functions in one, not give every single function its own dedicated file. That is rather counterproductive and may invite trouble eventually in regards of linking.
 
Hi Foxhood,

Thanks for suggesting the signal levels. I verified the data sheet and it said that anything >.5V was a high. So, I think we're good there.

From your forest comment, I decided to strip the program down to just the Teensy and the MCP41xx digipot code, but except for the chip select, I can't get even the simplest function (on-board LED) to work.
Features:
1. I've got an LED on the CS line - that works
2. Digipot Reg0 is adjusts the intensity of/for an LED
3. Digipot Reg1 adjusts the input to an op-amp
4. A pot input into A14 (phy pin 33) used to control both registers concurrently
5. Then added short code to control the on-board pin 13 LED using the same anal-pot. Even that doesn't work!

Both the LED and the op-amp input are dependent on the manual pot input.

I know the pot varies properly - I can measure at the A14 input
SerMon does not work
And I'm getting no response from the LED. And yes, it is wired in correctly.

Obviously, I'm doing silly, stupid stuff.

New, streamed-lined script attached.

Thanks,
Dave

I'm not seeing a way to attach my latest sketch file so I've embed the script here:
--------------------
//Program for the Prototype BreadBrd Experiment - Reading the Analog Pot Values and controlling digipots
#include <SPI.h> //SPI Control library

void spi_cs();

int ledPin = 13; // the built-in LED


int PotVal;
int PotValSave;


//=========== DigiPot Write & Read =================
//Define the Global CSAddressing lines and Register Writes for the DigiPots
const int CSA0 = 0; //CS Addr0/A0 (LSB). Teensy: D0
const int CSA1 = 1; //CS Addr1/A1 Teensy: D1
const int CSA2 = 2; //CS Addr2/A2 Teensy: D2
const int CSA3 = 3; //CS Addr3/A3 (MSB) Teensy: D3
//const byte ReadReg0= B00001100; //Register 0 Read command ; This may not be needed: SPI.transfer(0); is a 'read'
//const byte ReadReg1= B00011100; //Register 1 Read command
const byte WriteReg0 = B00000000; //Register 0 Write command ; Not needed for single-reg digipots: digitalWrite(pin, state); SPI.transfer(data);
const byte WriteReg1 = B00010000; //Register 1 Write command

SPISettings settingsA(2000000, MSBFIRST, SPI_MODE0);

void setup()
{
Serial.begin(9600); //Initialize the serial port to send and receive at 9600 baud

//Chip Select address lines to the 74xx154 4-to-16 line decoder chip
pinMode(CSA0, OUTPUT);
pinMode(CSA1, OUTPUT);
pinMode(CSA2, OUTPUT);
pinMode(CSA3, OUTPUT);

pinMode(A14, INPUT); //Is this needed??
pinMode(ledPin, OUTPUT);


// Flash each of the DigiPot LEDs
spi_cs(15); // This is the Parking Place Place Addr (1111) <<<<<

spi_cs(0); // Flash LED1 (CS0 Addr=0000)ON for 200ms.
delay(200);

spi_cs(15); // Turn off the CS line: Addr (1111) <<<<<

SPI.beginTransaction(settingsA); //Since we only have a single SPI settings, don't need an SPI.endTransaction();
SPI.begin(); //Initialize SPI

}


void loop()
{
// 1. Read manual pot (10-bit word) and value print to SerMon
// 2 If the new abs(potValSaved - potVal) >2 then ...
// 3. Output potValueA to digipot 1
// 4. Output potValueA to digipot 2
// 5. Delay a bit and repeat


PotVal = analogRead(A14); // read the input on analog pin A14:

Serial.print("Pot Value = "); Serial.println(PotVal); // print out the value read from the pot


if (abs(PotVal - PotValSave) > 2) {
spi_cs(0); //Sets CS Address=CS0=0000
delay(50); //Adding a delay so the LED flashes

SPI.transfer(WriteReg0); //Select to register 0 to receive value and function
SPI.transfer(PotVal); //Transfer the Resistance level value
delay(50);

SPI.transfer(WriteReg1); //Select to Register 1 to receive value and function
SPI.transfer(PotVal); //Transfer the Resistance level value
delay(10);
spi_cs(15); //Reset the CS (turn off), to the CS=15 state

Serial.println("Both Pot registers adjusted");
}

int PotValSave = PotVal;

delay (300) ; //Wait 300msec

// The following is to turn on the on-board pin 13 LED according to the pot value
int sensorValue = analogRead(PotVal); // read the value from the Pot:
digitalWrite(ledPin, HIGH); // turn the ledPin on
delay(sensorValue); // stop the program for <sensorValue> milliseconds:
digitalWrite(ledPin, LOW); // turn the ledPin off:
delay(sensorValue); // stop the program for for <sensorValue> milliseconds:
}


void spi_cs(int ChipSelect) {
//This routine is to make it easier and reduce possible Demux address coding
//errors. Here, we pass in the desired CS address and the correct CSA lines are set


switch (ChipSelect) {
case 0: //digipot: Ch1 Diver HdPh & Aux Input: 0000 = 0
digitalWrite(CSA0, LOW);
digitalWrite(CSA1, LOW);
digitalWrite(CSA2, LOW);
digitalWrite(CSA3, LOW);
break;

case 1: //digipot: Ch2 Diver Mic Input: 0001 = 1
digitalWrite(CSA0, HIGH);
digitalWrite(CSA1, LOW);
digitalWrite(CSA2, LOW);
digitalWrite(CSA3, LOW);
break;

case 2: //digipot: Pre-Amp Gain (PAG): 0010 = 2
digitalWrite(CSA0, LOW);
digitalWrite(CSA1, HIGH);
digitalWrite(CSA2, LOW);
digitalWrite(CSA3, LOW);
break;

case 3: //Digipot: LED Br: 0011 = 3
digitalWrite(CSA0, HIGH);
digitalWrite(CSA1, HIGH);
digitalWrite(CSA2, LOW);
digitalWrite(CSA3, LOW);
break;

case 4: // Pwr-Amp Bias(PAB) (future): 0100 = 4
digitalWrite(CSA0, LOW);
digitalWrite(CSA1, LOW);
digitalWrite(CSA2, HIGH);
digitalWrite(CSA3, LOW);
break;

case 5: // Tone Gen'r (On-Brd) / "FSYNC": 0101 = 5
digitalWrite(CSA0, HIGH);
digitalWrite(CSA1, LOW);
digitalWrite(CSA2, HIGH);
digitalWrite(CSA3, LOW);
break;

case 6: //digipot: Ch2 Diver HdPh & Aux Input: 0110 = 6
digitalWrite(CSA0, LOW);
digitalWrite(CSA1, HIGH);
digitalWrite(CSA2, HIGH);
digitalWrite(CSA3, LOW);
break;

case 7: // digipot: Ch2 Diver Mic Input: 0111 = 7
digitalWrite(CSA0, HIGH);
digitalWrite(CSA1, HIGH);
digitalWrite(CSA2, HIGH);
digitalWrite(CSA3, LOW);
break;

case 8: //digipot: Ch3 Diver HdPh & Aux Input: 1000 = 8
digitalWrite(CSA0, LOW);
digitalWrite(CSA1, LOW);
digitalWrite(CSA2, LOW);
digitalWrite(CSA3, HIGH);
break;

case 9: // digipot: Ch3 Diver Mic Input: 1001 = 9
digitalWrite(CSA0, HIGH);
digitalWrite(CSA1, LOW);
digitalWrite(CSA2, LOW);
digitalWrite(CSA3, HIGH);
break;

case 10: // Tone Gen'r (Ext-DigiBrd) / "FSYNC": 1010 = 10/A
digitalWrite(CSA0, LOW);
digitalWrite(CSA1, HIGH);
digitalWrite(CSA2, LOW);
digitalWrite(CSA3, HIGH);
break;

case 11: // Ext SPI Display: 1011 = 11/B
digitalWrite(CSA0, HIGH);
digitalWrite(CSA1, HIGH);
digitalWrite(CSA2, LOW);
digitalWrite(CSA3, HIGH);
break;

case 12: // (future)
digitalWrite(CSA0, LOW);
digitalWrite(CSA1, LOW);
digitalWrite(CSA2, HIGH);
digitalWrite(CSA3, HIGH);
break;

case 13: // (future)
digitalWrite(CSA0, HIGH);
digitalWrite(CSA1, LOW);
digitalWrite(CSA2, HIGH);
digitalWrite(CSA3, HIGH);
break;

case 14: // (future)
digitalWrite(CSA0, LOW);
digitalWrite(CSA1, HIGH);
digitalWrite(CSA2, HIGH);
digitalWrite(CSA3, HIGH);
break;

case 15: //The Parking Spot! : 1111 = 15/F

digitalWrite(CSA0, HIGH);
digitalWrite(CSA1, HIGH);
digitalWrite(CSA2, HIGH);
digitalWrite(CSA3, HIGH);
break;

}
}
 

Attachments

  • SPI_ChipSelect.ino
    3.4 KB · Views: 24
  • Teensy32_Demo_Pre-UI_DigiPot_EEPROM_PWM.zip
    14.6 KB · Views: 28
Last edited:
BTW, I was abel to attach (I think) the 2 .ino files to this thread. Hope they're attached.

Thanks,
Dave

Well, looks like I attached 1 file correctly. will try attaching the correct main file.
 

Attachments

  • SPI_ChipSelect.ino
    3.4 KB · Views: 28
  • Teensy32_DigiPot_InterDev_06Nov21.ino
    3.4 KB · Views: 28
Thanks for suggesting the signal levels. I verified the data sheet and it said that anything >.5V was a high. So, I think we're good there.
What voltage are you supplying to the digipot?

The logic inputs require <0.3Vdd and >0.7Vdd for low and high, ie <1.5V and >3.5V if powered from 5V, so these chips are
not 3.3V compatible if powered at 5V. Nowhere in the datasheet does it mention 0.5V, no idea how you got that?

Note the SPI clock frequency is a maximum of 10MHz (5V supply, not daisy-chained), or 5.8MHz (5V supply in daisy-chain
configuration). For 3.3V operation these will be considerably less, perhaps 4MHz and 2MHz are safe values to assume, as CMOS is
always slower at lower supply. Thus your SPI settings at 2MHz should be good, I suspect the voltage thresholds might be the problem
if running them at 5V.
 
SPI.beginTransaction(settingsA); //Since we only have a single SPI settings, don't need an SPI.endTransaction();
SPI.begin(); //Initialize SPI

Use SPI.begin() before SPI.beginTransaction().
 
Hi Paul. Ok. Will do.

Hi MarkT. Sometimes these one datasheet to cover many products can be confusing, and I admit, I spent awhile reading this one. And just in case you're right, I'll try using 10k/20k pull-ups on the SCK/SDI lines. So, I went back into the data sheet and extracted images of the data I thought was relavent. Maybe I'm reading it wrong, but check out the 2 pgs of data I found. See: Digipot Data Taken from MCP4xxx...

I would still like to know why I can't get the SerMon to print or the on-board pin-13 LED to work. The USB port connection is fine.
 

Attachments

  • Digipot Data Taken from the MCP4xxx Datasheet.pdf
    539.7 KB · Views: 30
Ok, some good news here. Switching SPI.begin() before SPI.beginTransaction() fixed a couple things:
1. SerMon now works.
2. The code is reading the analog pot input and reported to the SerMon window.
3. The CS LED to the digipot is irratically flashing, which tells me the if loops works.

What's not working is the LED on the digipot. Maybe the pull-up R's will fix that? Do I need a level translator?

Thanks,
Dave
 
Ok, some more good news. The digipot LED is at least glowing at mid-range where it defaults to with no new value in on-board EE. I thought the LED was wired correctly - it was not. Now having a glow, tells me it's now wired correctly, but not receiving a new SPI input.
 
Hi MarkT. Sometimes these one datasheet to cover many products can be confusing, and I admit, I spent awhile reading this one. And just in case you're right, I'll try using 10k/20k pull-ups on the SCK/SDI lines.
So, I went back into the data sheet and extracted images of the data I thought was relavent. Maybe I'm reading it wrong, but check out the 2 pgs of data I found. See: Digipot Data Taken from MCP4xxx...

I would still like to know why I can't get the SerMon to print or the on-board pin-13 LED to work. The USB port connection is fine.
Ah, I think my search for "MCP41xx datasheet" took me to MCP41xxx as a first hit rather than MCP41xx, which are different. A precise part number is always a better starting point for a datasheet search...
 
Hi Paul, Mark T,

Just in case I wasn't reading the data sheets correctly, I inserted a 74AHCT125 buffer (level transceiver) in the between the Teensy and the digipots on the SCK and SDI lines. It did not make a difference. I am satisfied it's not the circuit HW. It's got to be the code.

Any more suggestions?

Thanks,
Dave
 
I am satisfied it's not the circuit HW. It's got to be the code.

Any more suggestions?


I hope you can understand any more suggestions at this point would amount to blind guessing, since you've changed the hardware and software, and as far as I can see we still don't even know the exact part number of the digipot chip you're really using.

Maybe a better approach at this point would involve building the simplest possible test hardware on a solderless breadboard, and reducing your program to the minimum possible code to demonstrate the problem. Then show us photos of the hardware and the complete program. I know your end goal is to get your large project working and this sort of effort probably feels like an unnecessary diversion. But simplifying it to the point you can show us enough detail, and hopefully well enough than I or anyone else who might have that particular digipot part (I have many here, but they're all the I2C type) could quickly build it the same way and run your code to reproduce the problem.

Problems we can see are easier to solve, and problems we can actually reproduce are even better. Please try to move in that direction, as it seems we've made progress but ultimately stalled with just guesswork.
 
Hi Paul, Mark T,

Attached is the schematic of the dual-digipot(MCP4231) test brd and a captioned pic of the digipot test brd.. Thru one digipot I want to test an audio signal. On the other side, I'm using the digipot to control the current thru an LED.

I have a CS LED that flashes for any value (not a difference value like the code is written) > 2, so not sure what is going on there.

I have confirmed that near-5V signals are reaching the SCK and SDI inputs.

If you need any additional info, pls let me know.

Thanks in advance for all your help.

Thanks,
Dave
 

Attachments

  • Schematic_Teensy & Digipot Audio Test Brd_2021-11-10 (2).pdf
    67.9 KB · Views: 35
  • Teensy3.2 Audio Test Brd Captioned (11Nov21).jpg
    Teensy3.2 Audio Test Brd Captioned (11Nov21).jpg
    250.8 KB · Views: 34
In your schematic, I don't see any connection to pin 14 (VCC) on the 74AHCT125 chip.

The schematic seems to show a 20 pin ribbon cable. But in the photo I see only 5 wires.

Your message says you're using MCP4231, but the schematic says MCP4241-103.

Looks like Teensy 3.2 is in a socket, and the MCP4231 chip is DIP package also in a socket. So perhaps for a simpler test, you could unplug Teensy 3.2 and the MCP4231 from this complicated circuitry and put them both on a solderless breadboard without any other stuff (other than wires)? The nice thing about breadboards is they (usually) photograph pretty well, so we can see how the wires are really connected. We can help you much better if we can actually see the wiring, and if the wiring is as simple as possible.

For simple testing, I'd suggest connecting just power and CS,MOSI,SCK directly from Teensy to MCP4231, and connect the pot A terminal to GND and B terminal to 3.3V, and connect a voltmeter to the W terminal, so you can directly observe the result.
 
Hi Paul, Mark T,

I did what you suggested, I stripped the circuit down to just the Teensy 3.2, the MCP4241 digipot, and manual input pot. Attached are three files: 1) the schematic, 2) pic of the prototyped circuit (w/LEDs), and 3) the revised sketch.

There are 2 LEDs in the circuit: 1) a red load LED attached to the 10k controlling digipot, and 2) a white LED on the Chip Select line. The CS line shows when data is transmitted.

I am able to control the load LED better, but there are 3 behaviors which I don't have an answer: 1)I'm missing the upper 1/3 of the manual pot range, 2) D6 from the Teensy does not appear to go high, so I'm not getting full brightness, and 3) the CS line is taken low every loop around even when I'm not adjusting the pot - I have it coded so it only sends data when there is a change of the pot.

I do a conversion from the 10-bit analog input to the 7-bit digipot.

I believe I'm not able to extinguish the red LED because I'm only using a 10k pot. I may need a 50k pot. 25k is not available.

I made a 64sec video to show all the behaviors above, if you are able to view it. Will your system allow me to upload a 30MB .MOD file?

Thank you!
Dave
 

Attachments

  • Schematic_Teensy & Digipot Audio Test Brd_Sht2_13Nov21.pdf
    44.6 KB · Views: 28
  • Teensy32_DigiPot_InterDev_Stripped_13Nov21.ino
    2.5 KB · Views: 26
  • Teensy32-to-4241DigipotMinimal(13Nov21).jpg
    Teensy32-to-4241DigipotMinimal(13Nov21).jpg
    280.4 KB · Views: 23
1) This is not to do with the pot value, you need to give the pot 3.3V, not 5V, so all of the track is useful.
2) Nothing is connected to D6 on the Teensy according to your circuit.
3) This might just be a bit of jitter on the analog input - even though you have a capacitor there the ADC
is relative to the supply which may have enough noise on it to add a few LSBs of jitter.

Link to external video hosting site is the way to do video.

Post the code in code tags please.
 
Hi MarkT, Paul,

1. That makes sense. So, I attached the high side of the pot to the 3.3 pin. In the video, ignore the comments about the 1 o'clock position.
2. Clarification - I should not have called it "D6". What I was referring to was the 6th bit (2nd most sig bit) of the SPI serial string - easily seen in the video.
3. You're right, noise on the input affects the lowest couple of bits, but that's not the issue. Pls see the video.

Link to the DropBox video: https://www.dropbox.com/s/buk0fg99q2hmmbe/MOV099.MOD?dl=0

I tested the link and downloading may be required.

Mark, I don't know what "post the code in code tags" means.

Thanks,
Dave
 
Mark, I don't know what "post the code in code tags" means.

First, in Arduino copy all your code to the clipboard. This is easiest by CTRL-A to select all, then CTRL-C to copy.

Then on the forum, click this button.

screenshot.png

You will see the 2 code tags appear and your cursor should be between them. If not, click between them so the cursor is after the first tag and before the 2nd tag. Then press CTRL-V to paste all you code.

Click "Go Advanced" or "Preview Post" to see the result. Your code's white space is preserved.
 
Code:
//Program for the Prototype BreadBrd Experiment - Reading the DigiPot Values
#include <SPI.h>        //SPI Control library
//#include <EEPROMex.h>     //EEPROM library


int ledPin = 13; // the built-in LED


int PotVal;
int PotValSave;


//===========   DigiPot Write & Read    =================
//Define the Global CSAddressing lines and Register Writes for the DigiPots
const int CSA0 = 0;   //CS Addr0/A0 (LSB).  Teensy: D0 

const byte WriteReg0 = B00000000; //Register 0 Write command ;    Not needed for single-reg digipots:  digitalWrite(pin, state) > SPI.transfer(data);
const byte WriteReg1 = B00010000; //Register 1 Write command

SPISettings settingsA(2000000, MSBFIRST, SPI_MODE0);

void setup()
{
  Serial.begin(9600);   //Initialize the serial port to send and receive at 9600 baud

  //Chip Select address lines to the 74xx154 4-to-16 line decoder chip
  pinMode(CSA0, OUTPUT);
//  pinMode(A7, INPUT);    //Is this needed??
  pinMode(ledPin, OUTPUT);  

  
  digitalWrite(CSA0, LOW);        // Flash the CS LED
  delay(200);
  digitalWrite(CSA0, HIGH);

  SPI.begin();                    //Initialize SPI
  SPI.beginTransaction(settingsA);    //Since we only have a single SPI settings, don't need an SPI.endTransaction();

}


void loop()  {
  // 1. Read manual pot (10-bit word), convert to 7-bit (div by 8), and print value to SerMon
  // 2 If the new abs(potValSaved - potVal) < 2, then skip if and loop.  Else..
  // 3. Output potVal to digipot 0
  // 4. Output potVal to digipot 1
  // 5. Delay a bit and repeat

  PotVal = int (analogRead(A7)/8);         // Turn the 1023 value into a 126 value:

  Serial.print("Pot Value = "); Serial.println(PotVal);   // print out the value read from the pot


  if (abs(PotVal - PotValSave) > 2) {
    digitalWrite(CSA0, LOW);                 //Sets CS=Low
    delay(5);                    //Adding a delay so the LED flashes

    SPI.transfer(WriteReg0);     //Select to register 0 to receive value and function
    SPI.transfer(PotVal);        //Transfer the new value to the digipot Reg0
    delay(5);
    
    SPI.transfer(WriteReg1);     //Select to Register 1 to receive value and function
    SPI.transfer(PotVal);        //Transfer the new value to the digipot Reg1
    delay(10);
    digitalWrite(CSA0, HIGH);    //Return CS to High

    Serial.print("Value written to the Pot registers: "); Serial.println(PotVal);
  }

  int PotValSave = PotVal;

  delay (300) ;          //Wait 300msec
  
}
 
Hi Paul, Mark T,

Any thoughts as to why the 6th bit is not being output (as it appeared on the DSO) from the Teensy?

Also, I measured to the current thru the load LED and at the low end, there's still ~675uA current. Apparently, still plenty to make the LED glow. I'm guessing I'll have to use a 50k pot.

Thanks,
Dave
 
Paul, Mark T,

After trying the code in a different Teensy (no change), I re-counted the bits that are working. All lower 7 bits are being transmitted and received by the digipot. That tells me that the MSB is not being transmitted.

Am I looking at this correctly? Is there something I'm not doing properly?

Thanks,
Dave
 
Status
Not open for further replies.
Back
Top