CD74HC4067 MUX example code using STM32F103

Post here first, or if you can't find a relevant section!
justinjools
Posts: 41
Joined: Thu May 02, 2024 11:10 am

CD74HC4067 MUX example code using STM32F103

Post by justinjools »

Hi,
I was using a CD74HC4067 library for Arduino with Arduino Nano. Now I tried it with STM32 but it doesn't accept the pin numbers so is obviously for ATMega MCUs only. Is there any MUX example for CD74HC4067? I did look at the STMDuino SPI loop example but is not specifically for multiplexers.
STM32ardui
Posts: 142
Joined: Mon May 06, 2024 1:46 pm
Answers: 1
Location: Germany

Re: CD74HC4067 MUX example code using STM32F103

Post by STM32ardui »

STM32 MCUs have numbers like PA0, PA2 ... PB0, PB1 ... and so on.
There are a lot of pinout-diagrams in internet, where you can see it.

A multiplexer has nothing to do with SPI.
74HC4067 simply needs 4 input pins. If there is a library for such a mulitplexer, it may "translate" a channel 0 ... 15 to a combination of these 4 input pins.
justinjools
Posts: 41
Joined: Thu May 02, 2024 11:10 am

Re: CD74HC4067 MUX example code using STM32F103

Post by justinjools »

Yes, I realise MUX has nothing to do with SPI after I wrote, I was trying to find some code that might help and that's all I could find for defining pins. (STMDuino library isn't very useful)
I know all the pinouts for STM32. My point is the MUX Arduino library examples don't work with STM32 pinouts PA, PB. They only accept numbers.

To be explicit this is an Arduino MUX library example

https://github.com/RobTillaart/HC4067/b ... uttons.ino

//
// FILE: HC4067_demo.ino
// AUTHOR: Rob Tillaart
// PURPOSE: Demo for HC4067 16 channel (simple) multiplexer
// read 16 buttons / switches.
// URL: https://github.com/RobTillaart/HC4067


#include "HC4067.h"

HC4067 mp(4, 5, 6, 7); // no enable pin defined connect to GND.

const int inputPin = 10;
uint16_t values;


void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("HC4067 LIBRARY VERSION: ");
Serial.println(HC4067_LIB_VERSION);
Serial.println();

pinMode(inputPin, INPUT);

}


void loop()
{
int channel = 16;
values = 0;
while (channel > 0)
{
channel--;
mp.setChannel(channel);
values <<= 1;
if (digitalRead(inputPin) == HIGH) values += 1;
}
Serial.println(values, HEX);
delay(1000);
}


// -- END OF FILE --
Last edited by justinjools on Tue Jul 02, 2024 7:52 pm, edited 1 time in total.
ag123
Posts: 1898
Joined: Thu Dec 19, 2019 5:30 am
Answers: 30

Re: CD74HC4067 MUX example code using STM32F103

Post by ag123 »

well I took a look at the datasheet e.g.
16-channel analog multiplexer/demultiplexer
https://assets.nexperia.com/documents/d ... CT4067.pdf
from the 5. functional diagram
you have 4 inputs s0 - s3 that select the lines. And lets just say you assign pa0-pa3 on stm32f103 to drive s0-s3.
and that you toggle the enable pin additionally and lets ay use pa4 for that.
and pa5 for the output;
the codes would look something like

Code: Select all

uint8_t s0, s1, s2, s3, enable, output;
s0 = 1;
s1 = 0;
s2 = 1;
s3 = 0;
enable = 1; // active low, so this is disabled
digitalWrite(PA4, enable);
digitalWrite(PA0, s0);
digitalWrite(PA1, s1);
digitalWrite(PA2, s2);
digitalWrite(PA3, s3);
output = 1;
digitalWrite(PA5, output);
enable = 0; // enable
digitalWrite(PA4, enable);
this should show the output on the 5th multiplexed pin

there are faster ways to do this, just not as 'arduinoish', e.g.

Code: Select all

digitalWrite(PA4, 1); //disable
GPIOA->BSRR = 0b100101;
GonzoG
Posts: 491
Joined: Wed Jan 15, 2020 11:30 am
Answers: 36
Location: Prudnik, Poland

Re: CD74HC4067 MUX example code using STM32F103

Post by GonzoG »

You don't need any library. Just set 4 pins for selecting input/output and pin for read/write.
I/O selection is binary coded

Simple function to select multiplexer port:

Code: Select all

void selectPort(int8_t port)
{
	if(port<0 || port>15)
		return;
	digitalWrite(pin1,  port&1);
	digitalWrite(pin2,  (port>>1)&1);
	digitalWrite(pin3,  (port>>2)&1);
	digitalWrite(pin4,  (port>>3)&1);	
}
STM32ardui
Posts: 142
Joined: Mon May 06, 2024 1:46 pm
Answers: 1
Location: Germany

Re: CD74HC4067 MUX example code using STM32F103

Post by STM32ardui »

justinjools wrote: Tue Jul 02, 2024 6:49 pm I was trying to find some code that might help and that's all I could find for defining pins. (STMDuino library isn't very useful)
https://github.com/stm32duino/Arduino_C ... n/variants
There you find for each STM32-family pin definitions.
In variant_generic.h you see a lot of #define preprocessor directives.
Don't know, why your IDE doesn't translate a PA2 or something else.
justinjools wrote: Tue Jul 02, 2024 6:49 pm

Code: Select all

//Mux control pins
int s0 = 8;
int s1 = 9;
int s2 = 10;
int s3 = 11;
Bad idea!
PA9 and PA10 are for serial port and PA11 for USB.



@all:
What happens with lines like

Code: Select all

#define PB0                     PIN_A8
#define PB1                     PIN_A9
PB0 = 16 and PB1 = 17 ?
That "PIN_A8" and "PIN_A9" is only an additional information, that it can be a analog pin?
And it numbered consecutively, because the "last" analog pin is PA7 or PIN_A7?
In variant_generic.cpp I see a array for analog pins, here the integer value with comments to pin decription:

Code: Select all

16, // A8,  PB0
17  // A9,  PB1
That's difficult to understand for a newbie ...
justinjools
Posts: 41
Joined: Thu May 02, 2024 11:10 am

Re: CD74HC4067 MUX example code using STM32F103

Post by justinjools »

Hi, Arduino IDE does understand STM pin numbers with some libraries I've used. e.g. MCP48/49 works well.

I'm find it a little difficult to understand the code you shared. I am reading pot values. These are the pins I want to use:

S0 - PB12
S1 - PB13
S2 - PB14
S3 - PB15
Analogue Signal pin - A6

Something like this? Still confused what exactly the code should be.

//Mux control pins
int S0 = PB12;
int S1 = PB13;
int S2 = PB14;
int S3 = PB15;

//Mux in "SIG" pin
int SIG_pin = PA6;

void selectPort(int8_t port)
{
if(port<0 || port>15)
return;
digitalRead(S0, port&1);
digitalRead(S1, (port>>1)&1);
digitalRead(S2, (port>>2)&1);
digitalRead(S3, (port>>3)&1);
}
justinjools
Posts: 41
Joined: Thu May 02, 2024 11:10 am

Re: CD74HC4067 MUX example code using STM32F103

Post by justinjools »

I found this code I used before with Arduino Nano and apapted it and it compiles and uploads so I guess that's a good sign. But now I can't connect to get the serial monitor with usb.

How do I use the serial monitor with STM32?

#include <CD74HC4067.h>

//Mux control pins
int s0 = PB12; // 8;
int s1 = PB13; // 9;
int s2 = PB14; // 10;
int s3 = PB15; // 11;

//Mux in "SIG" pin
int SIG_pin = PA6;


void setup(){
pinMode(s0, OUTPUT);
pinMode(s1, OUTPUT);
pinMode(s2, OUTPUT);
pinMode(s3, OUTPUT);

digitalWrite(s0, LOW);
digitalWrite(s1, LOW);
digitalWrite(s2, LOW);
digitalWrite(s3, LOW);

Serial.begin(9600);
}


void loop(){

//Loop through and read all 16 values
//Reports back Value at channel 6 is: 346
for(int i = 0; i < 16; i ++){
Serial.print("Value at channel ");
Serial.print(i);
Serial.print("is : ");
Serial.println(readMux(i));
delay(1000);
}

}


int readMux(int channel){
int controlPin[] = {s0, s1, s2, s3};

int muxChannel[16][4]={
{0,0,0,0}, //channel 0
{1,0,0,0}, //channel 1
{0,1,0,0}, //channel 2
{1,1,0,0}, //channel 3
{0,0,1,0}, //channel 4
{1,0,1,0}, //channel 5
{0,1,1,0}, //channel 6
{1,1,1,0}, //channel 7
{0,0,0,1}, //channel 8
{1,0,0,1}, //channel 9
{0,1,0,1}, //channel 10
{1,1,0,1}, //channel 11
{0,0,1,1}, //channel 12
{1,0,1,1}, //channel 13
{0,1,1,1}, //channel 14
{1,1,1,1} //channel 15
};

//loop through the 4 sig
for(int i = 0; i < 4; i ++){
digitalWrite(controlPin, muxChannel[channel]);
}

//read the value at the SIG pin
int val = analogRead(SIG_pin);


//return the value
// float voltage = (val * 5.0) / 1024.0;
// return voltage;
return val;
}
STM32ardui
Posts: 142
Joined: Mon May 06, 2024 1:46 pm
Answers: 1
Location: Germany

Re: CD74HC4067 MUX example code using STM32F103

Post by STM32ardui »

justinjools wrote: Tue Jul 02, 2024 8:42 pm I found this code I used before with Arduino Nano and apapted it and it compiles and uploads so I guess that's a good sign. But now I can't connect to get the serial monitor with usb.
Take a look at some of these pinout diagrams: PA11 and PA12 are for USB.
What will happen, if you use one of those pins for multiplexer chip?
justinjools wrote: Tue Jul 02, 2024 8:42 pm How do I use the serial monitor with STM32?
FTDI-adapter (or Serial-to-USB-adapter).

It would be nice, if you put your sketch in code-Tags! It's the icon "</>"
GonzoG
Posts: 491
Joined: Wed Jan 15, 2020 11:30 am
Answers: 36
Location: Prudnik, Poland

Re: CD74HC4067 MUX example code using STM32F103

Post by GonzoG »

justinjools wrote: Tue Jul 02, 2024 8:13 pm Hi, Arduino IDE does understand STM pin numbers with some libraries I've used. e.g. MCP48/49 works well.

I'm find it a little difficult to understand the code you shared. I am reading pot values. These are the pins I want to use:

S0 - PB12
S1 - PB13
S2 - PB14
S3 - PB15
Analogue Signal pin - A6

Something like this? Still confused what exactly the code should be.

//Mux control pins
int S0 = PB12;
int S1 = PB13;
int S2 = PB14;
int S3 = PB15;

//Mux in "SIG" pin
int SIG_pin = PA6;

void selectPort(int8_t port)
{
if(port<0 || port>15)
return;
digitalRead(S0, port&1);
digitalRead(S1, (port>>1)&1);
digitalRead(S2, (port>>2)&1);
digitalRead(S3, (port>>3)&1);
}
Exactly like this.

And now in loop() you just execute selectPort() and read/write from/to signal pin.
example:

Code: Select all

uint16_t potData[16];

void loop(){
	for (uint8_t i=0;i<16;i++)
	{ 
		selectPort(i);
		//delayMicroseconds(1); //with analogRead() delay shouldn't be needed, as setting everything analog read should take more time than hc4067 needs to switch.
		potData[i]=analogRead(SIG_pin);
	}
}
justinjools wrote: Tue Jul 02, 2024 8:42 pm ...But now I can't connect to get the serial monitor with usb.

How do I use the serial monitor with STM32?
It all depends on what board you're using.
Pills (blue, black, red, green, etc) have direct USB connection. You just need to enable USB CDC (supersede Serial) in arduino menu -> Tools.

Nucleo boards have built-in ST-Link for programming, but it usually isn't connected to serial output, you may need to solder some jumpers or wires to use usb port.
Other way is to use USB-TTL adapter (ch340, PL2303, ftdi, etc) and connect it to one of available UARTs.
Post Reply

Return to “General discussion”