update selector mechanism menggunakan 4 demultiplexer 74LS138
parent
39cb305fe8
commit
c8796cd9b9
Binary file not shown.
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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: [
|
||||
|
|
Loading…
Reference in New Issue