update selector mechanism menggunakan 4 demultiplexer 74LS138

software
a2nr 2024-10-25 19:36:02 +07:00
parent 39cb305fe8
commit c8796cd9b9
5 changed files with 125 additions and 93 deletions

Binary file not shown.

View File

@ -4,13 +4,13 @@ import 'dart:io';
class X9c10x {
final int _id;
final int _ohm;
//final int _ohm;
final GPIO _inc;
final GPIO _ud;
final GPIO? _ss;
final _log = Logger("X9C10X");
Function(int)? _onSelect;
Function(int)? _onRelease;
final Function(int)? _onSelect;
final Function(int)? _onRelease;
X9c10x({
required int id,
@ -20,13 +20,15 @@ class X9c10x {
GPIO? ss,
dynamic Function(int)? onSelect,
dynamic Function(int)? onRelease,
}) : _onRelease = onRelease, _onSelect = onSelect, _ss = ss, _ud = ud, _inc = inc, _ohm = ohm, _id = id;
}) : _onRelease = onRelease, _onSelect = onSelect, _ss = ss, _ud = ud, _inc = inc, _id = id;
void _selectChip(){
_onSelect?.call(_id);
_ss?.write(false);
_log.info("_selectChip() <$_id>");
}
void _releaseChip(){
_log.info("_releaseChip() <$_id>");
_ss?.write(true);
_onRelease?.call(_id);
}
@ -35,11 +37,11 @@ class X9c10x {
void _storeSkip()=>sleep(const Duration(milliseconds: 20));
Future<void> wipeUp() async {
_log.info("wipeUp()");
_selectChip();
_ud.write(true);
_skip();
_inc.write(false);
while(true){} //TODO: DEAD CODE;
_skip();
_inc.write(true);
_releaseChip();
@ -47,6 +49,7 @@ class X9c10x {
}
Future<void> wipeDown() async {
_log.info("wipeDown()");
_selectChip();
_ud.write(false);
_skip();

View File

@ -36,7 +36,7 @@ class Ads1256 {
String? tag,
int? pinReset,
int? pinCS }){
spi = SPI(spiBus, spiChip, SPImode.mode1, 500000);
spi = SPI(spiBus, spiChip, SPImode.mode1, 50000);
drdy = GPIO(pinDrdy, GPIOdirection.gpioDirIn, gpioChip);
cs = pinCS != null ? GPIO(pinCS, GPIOdirection.gpioDirOutHigh, gpioChip): null;
rst = pinReset != null ? GPIO(pinReset, GPIOdirection.gpioDirOutHigh, gpioChip): null;
@ -108,16 +108,16 @@ class Ads1256 {
void csOn(){
cs?.write(isCSActiveHigh?true:false);
//skipClk();
//skipClk();
skipClk();
skipClk();
skipClk();
log.info(" > Start transfer");
}
void csOff(){
log.info(" > End transfer");
cs?.write(isCSActiveHigh?false:true);
//skipClk();
//skipClk();
skipClk();
skipClk();
skipClk();
}
@ -134,15 +134,18 @@ class Ads1256 {
bufferNCS = buffen;
autoCalibrationNCS = true;
clockOutRateNCS = CLKOUT_OFF;
programmableGainNCS = gain;
dataRateNCS = drate;
var st = statusNCS.toRadixString(16);
var ac = controlRegisterNCS.toRadixString(16);
var dt = dataRateNCS.toRadixString(16);
csOff();
log.info(" status : $st");
log.info(" adcon : $ac");
programmableGainNCS = gain;
var st = statusNCS.toRadixString(16);
log.info(" status : $st");
dataRateNCS = drate;
var dt = dataRateNCS.toRadixString(16);
log.info(" drate : $dt");
csOff();
skipClk();
calibrateOffsetGain();
}

View File

@ -27,7 +27,7 @@ class HeartBeatMice {
HeartBeatMice(){
var inc = GPIO(205, GPIOdirection.gpioDirOutHigh, 1);
var ud = GPIO(204, GPIOdirection.gpioDirOutHigh, 1);
gain = List<X9c10x>.generate(15, (i){
gain = List<X9c10x>.generate(16, (i){
return X9c10x(
id: i,
ohm: 104000,
@ -37,7 +37,7 @@ class HeartBeatMice {
onRelease: _releaseGain,
);
}, growable: false);
offset = List<X9c10x>.generate(15, (i){
offset = List<X9c10x>.generate(16, (i){
return X9c10x(
id: i,
ohm: 104000,
@ -52,11 +52,14 @@ class HeartBeatMice {
void init(){
adc1.begin(Ads1256.DRATE_500SPS, Ads1256.GAIN_1, true);
adc2.begin(Ads1256.DRATE_500SPS, Ads1256.GAIN_1, true);
adc1.ioDir = [Ads1256.IO_DIR_OUT, Ads1256.IO_DIR_OUT, Ads1256.IO_DIR_OUT, Ads1256.IO_DIR_OUT];
adc1.dIO = [false, false, false, false]; //selec A B C NC
log.info(" adcon : ${adc1.controlRegisterNCS.toRadixString(16)}");
adc2.begin(Ads1256.DRATE_500SPS, Ads1256.GAIN_1, true);
adc2.ioDir = [Ads1256.IO_DIR_OUT, Ads1256.IO_DIR_OUT, Ads1256.IO_DIR_OUT, Ads1256.IO_DIR_OUT];
adc1.dIO = [true, true, true, false]; // SIG2 SIG1 EN2 EN1
adc2.dIO = [false, false, false, false]; // S0 S1 S2 S3
adc2.dIO = [false, false, false, false]; //mux 0 1 2 3
log.info(" adcon : ${adc2.controlRegisterNCS.toRadixString(16)}");
}
@ -65,8 +68,7 @@ class HeartBeatMice {
//TODO: check kebenaran
var adc = switch (no) {
1 || 2 || 3 || 4 || 9 || 10 || 11 || 12 =>adc2,
5 || 6 || 7 || 8 || 13 || 14 || 15 || 16 || _ =>adc1,
};
5 || 6 || 7 || 8 || 13 || 14 || 15 || 16 || _ =>adc1, };
//TODO: check kebenaran
var ain = switch (no) {
1 || 13=>Ads1256.MUXP_AIN0,
@ -89,61 +91,67 @@ class HeartBeatMice {
void _signalMux(int n, bool val) {
log.info('_signalMux() <$n> <$val>');
int i = switch (n) {
1 => 1,
2 => 0,
1 => 0,
2 => 1,
3 => 2,
4 => 3,
_ => -1
};
log.info(' >mux : $i');
if (i == -1){
return;
}
var adc = adc1;
var adc = adc2;
List<bool> io = adc.dIO;
log.info(' >current <$io>');
io[i] = val; //SIG
io[i+2] = !val; //EN
//io[i] = val; //SIG
io[i] = val; //EN
adc.dIO = io;
log.info(' >confirm <${adc.dIO}>');
}
void _channelMux(int v) {
int val = v-1;
var adc = adc2;
log.info('_channelMux() <${val.toRadixString(16)}>');
int val = (v%8 == 0 ? 8: v%8).toUnsigned(8)-1;
var adc = adc1;
log.info('_channelMux() <$v>');
log.info(' >val : <$val>');
log.info(' >current <${adc.dIO}>');
adc.dIO = val.toListBoolbit();
log.info(' >confirm <${adc.dIO}>');
}
int _routeMux(an) => switch(an){
1 ||2 || 3|| 4|| 5|| 6|| 7|| 8 =>1,
9 ||8 || 10|| 11|| 12|| 13|| 14|| 15 =>2,
_ => -1
1 ||2 ||3 ||4 => 3,
9 ||10 ||11 ||12 => 2,
5 ||6 ||7 ||8 => 4,
13 ||14 ||15 => 1,
_=>1
};
void _selectOffset(int an){
log.info('_selectOffset() <${an.toRadixString(16)}>');
int n = _routeMux(an);
int n = _routeMux(an+1);
if (n == -1){
return;
}
_channelMux((an*2)-1); // - 1 for offset
_channelMux(((an+1)*2-1)); // - 1 for offset
_signalMux(n, true);
}
void _releaseOffset(int an){
log.info('_releaseGain() <${an.toRadixString(16)}>');
int n = _routeMux(an);
int n = _routeMux(an+1);
_signalMux(n, false);
}
void _selectGain(int an){
log.info('_selectGain() <${an.toRadixString(16)}>');
int n = _routeMux(an);
int n = _routeMux(an+1);
if (n == -1){
return;
}
_channelMux((an*2)-2); // - 2 for gain
_channelMux(((an+1)*2)); // - 0 for gain
_signalMux(n, true);
}
void _releaseGain(int an){
log.info('_releaseGain() <${an.toRadixString(16)}>');
int n = _routeMux(an);
int n = _routeMux(an+1);
_signalMux(n, false);
}

View File

@ -48,6 +48,7 @@ class MyHomePage extends StatefulWidget {
class _MyHomePageState extends State<MyHomePage> {
late HeartBeatMice device;
Logger log = Logger("_MyHomePageState");
int index = 1;
@override
void initState() {
@ -61,65 +62,85 @@ class _MyHomePageState extends State<MyHomePage> {
device.dispose();
}
Widget myProbe(double height,double width, int index){
return Column(
children: <Widget>[
Text("Analog $index"),
Column(children: [
Row(children: [
Row(children: [
IconButton(
onPressed: () async {device.offset[index-1].wipeUp();} ,
icon: const Icon(Icons.arrow_drop_up_outlined)),
const Text("Offset"),
IconButton(
onPressed: () async {device.offset[index-1].wipeDown();} ,
icon: const Icon(Icons.arrow_drop_down_outlined))
]),
Row(children: [
IconButton(
onPressed: () async {device.gain[index-1].wipeUp();} ,
icon: const Icon(Icons.arrow_drop_up_outlined)),
const Text("Gain"),
IconButton(
onPressed: () async {device.gain[index-1].wipeDown();} ,
icon: const Icon(Icons.arrow_drop_down_outlined)),
]),
],),
],
),
SizedBox (
height: height.toDouble(),
width: width,
child : Plot(
title: "Analog $index",
aspectRatio: (height/ width),
minY: -5,
maxY: 5,
maxTimeSeconds: 0.5,
sampleTimeMicross: 1,
readAnalog: () async { return device.readAnalog(index); }
),
),
],
);
}
@override
Widget build(BuildContext context) {
double height = 300;
double width = (MediaQuery.of(context).size.width-30);
double width = (MediaQuery.of(context).size.width-100);
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Row(children: [
body:
Row(children: [
IconButton(
onPressed: () {setState(() {index = ((index -1) < 1 ) ? 1 : index;});} ,
icon: const Icon(Icons.navigate_before)),
SizedBox(
width: width,
child: ListView.builder(
itemCount: 1,
itemBuilder: (context, i){
var index = i+1;
return Column(
children: <Widget>[
Text("Analog $index"),
Column(children: [
Row(children: [
Row(children: [
IconButton(
onPressed: () async {device.offset[index].wipeUp();} ,
icon: const Icon(Icons.arrow_drop_up_outlined)),
const Text("Offset"),
IconButton(
onPressed: () async {device.offset[index].wipeDown();} ,
icon: const Icon(Icons.arrow_drop_down_outlined))
]),
Row(children: [
IconButton(
onPressed: () async {device.gain[index].wipeUp();} ,
icon: const Icon(Icons.arrow_drop_up_outlined)),
const Text("Gain"),
IconButton(
onPressed: () async {device.gain[index].wipeDown();} ,
icon: const Icon(Icons.arrow_drop_down_outlined)),
]),
],),
],
),
SizedBox (
height: height.toDouble(),
width: width,
child : Plot(
title: "Analog $index",
aspectRatio: (height/ width),
minY: -5,
maxY: 5,
maxTimeSeconds: 0.5,
sampleTimeMicross: 1,
readAnalog: () async { return device.readAnalog(index); }
),
),
],
);
},
)),
child: myProbe(height, width, index)
),
IconButton(
onPressed: () {setState(() {index = ((index +1) > 16) ? 16 : index;});} ,
icon: const Icon(Icons.navigate_next)),
],)
);
}
}
// ListView.builder(
// itemCount: 1,
// itemBuilder: (context, i){
// var index = i+1;
// return ;
// },
// )
// SizedBox(
// width: width,
// child: ListView.builder(
@ -198,10 +219,7 @@ class _MyHomePageState extends State<MyHomePage> {
// );
// },
// )),
])
);
}
}
// Column(children: [
// Row(children: [