CD74HC4067 MUX example code using STM32F103
-
- Posts: 41
- Joined: Thu May 02, 2024 11:10 am
CD74HC4067 MUX example code using STM32F103
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.
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.
-
- Posts: 142
- Joined: Mon May 06, 2024 1:46 pm
- Location: Germany
Re: CD74HC4067 MUX example code using STM32F103
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.
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.
-
- Posts: 41
- Joined: Thu May 02, 2024 11:10 am
Re: CD74HC4067 MUX example code using STM32F103
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 --
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.
Re: CD74HC4067 MUX example code using STM32F103
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
this should show the output on the 5th multiplexed pin
there are faster ways to do this, just not as 'arduinoish', 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);
there are faster ways to do this, just not as 'arduinoish', e.g.
Code: Select all
digitalWrite(PA4, 1); //disable
GPIOA->BSRR = 0b100101;
Re: CD74HC4067 MUX example code using STM32F103
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:
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);
}
-
- Posts: 142
- Joined: Mon May 06, 2024 1:46 pm
- Location: Germany
Re: CD74HC4067 MUX example code using STM32F103
https://github.com/stm32duino/Arduino_C ... n/variantsjustinjools 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)
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.
Bad idea!justinjools wrote: Tue Jul 02, 2024 6:49 pmCode: Select all
//Mux control pins int s0 = 8; int s1 = 9; int s2 = 10; int s3 = 11;
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
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
-
- Posts: 41
- Joined: Thu May 02, 2024 11:10 am
Re: CD74HC4067 MUX example code using STM32F103
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);
}
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);
}
-
- Posts: 41
- Joined: Thu May 02, 2024 11:10 am
Re: CD74HC4067 MUX example code using STM32F103
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;
}
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;
}
-
- Posts: 142
- Joined: Mon May 06, 2024 1:46 pm
- Location: Germany
Re: CD74HC4067 MUX example code using STM32F103
Take a look at some of these pinout diagrams: PA11 and PA12 are for USB.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.
What will happen, if you use one of those pins for multiplexer chip?
FTDI-adapter (or Serial-to-USB-adapter).
It would be nice, if you put your sketch in code-Tags! It's the icon "</>"
Re: CD74HC4067 MUX example code using STM32F103
Exactly like this.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);
}
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);
}
}
It all depends on what board you're using.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?
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.