Muistikortin päälle/pois -kytkentä

Taas olisi pieni kysymys.

Käytössä on 328p kytkettynä “standardimallin” mukaan. Siinä on muistikortti kiinni nastoissa
MOSI, MISO, SCK sekä plus ja miinus. CS tai SS -nastana käytän muistaakseni pinniä 4 tai 5.
Muistikortin liitin on monessakin mielessä legendaarinen LC Studion tuote:

instructables.com/id/Arduino … ng-Shield/

Kaikki toimii ja kukkuu hienosti. Ongelmana on virrankäyttö. Muistikortin ollessa
aktiivinen se nappaa noin 15mA 5V käyttöjännitteellä. Kun nukutan 328:n, niin kortti
ottaa vieläkin noin 6mA: kun lukijasta ottaa varsinaisen SD-kortin ulos, niin virrantarve
tippuu 1.6 milliampeeriin. Ohjaan muistikortin jännitteensaantia N-fetillä, joka aktivoi
maatason, kun prosessori herää.

Ihmetystä herättää nyt, että mikä SD-puolella imee virtaa? Omat epäilykseni kohdistuvat
virransäätelyyn maatason puolelta. Ilmeisesti jonkinlaista “vuotoa” tms. tapahtuu MISO-
MOSI- ym. nastoista, jos kortinlukija saa plussapuolen jännitteen? Onko epäilykseni oikea?

Sinänsä kyrsii hieman, koska olen tehnyt PCB:n kuvaamallani nerokkaalla kytkennällä…
Tosin joudun tekemään piirikortin joka tapauksessa ainakin kertaalleen uusiksi. Ainakin
fet täytynee vaihtaa P-tyyppiseksi ja laittaa katkomaan plussapuolta. Oliskohan näin?

Muistithan vetää prossun kortille menevät I/O:t nollille nukkuessa? Tai ehkä vika onkin juuri siinä, että maadoittaa I/O:n kautta.

Ei jummarra ei.

Virransyönti on 6.3mA sleepissä kun SD-kortti on pitimessä, ja 1.6mA kun kortti on
pois lukijasta. Jotain “virtausta” siis tapahtuu. Ei tunnu olevan väliä, onko SD-kortissa
jännitteensyöttö kiinni (plus sekä miinus) vaiko ei. Aika mysteeri tämä mulle on.

Kokeilin 328-palikkaa myös koekytkentälevyllä, ja siellä (ilman ympäryskomponentteja
eli RTC-palikkaa ja SD-lukijaa) sleep-virta oli normi pari uA:ta, niin kuin pitääkin.

Pitäisiköhän virittää jonkinlainen kytkin, joka kytkee SD-kortin tarvittaessa kokonaan
irti MCU:sta? Tarvittaisiin viisi piuhaa päälle/poikki :slight_smile: Onkohan tämmöisiä piirejä
olemassa, on varmaan, voisi piruuttaan askarrella ja kokeilla, vaikka “ratkaisuna” tämä
on syvältä.

Luitko minun viestini?

Luin joskus kun etsiskelin SD kortin virransyönnistä niin siinä oli samanlainen vika. Muistaakseni vika oli niissä pikkunastoissa, eli ne koskivat maatasoon. Tarkistappas ne pinnit jotka on siellä reunassa jotka tunnistaa kun kortin laittaa paikoilleen…

Teg:

En ihan tajunnut mitä tarkoitat.

Prossulta tulee (Arduinon numerointi) 10, 11, 12,13. Lisäksi SD-kortin + -nasta on
plussassa. SD-kortin maanasta on fetin drainissa, ja fetin source on maassa, gate
vastuksen kautta prossun pinnissä 9, jolla ohjaan fettia (N-tyyppi siis BS170).
Mitä siis pitäisi vetää nollille ja miten?

Tumppu88:

Kiinanihme LC Studion SD-korteista on kirjoiteltu paljonkin… ja kummallisuuksia tuntuu
olevan. Tarkistan pikkunastat, ilmeisesti tarkoitat kortin pitkällä sivulla olevia? Eräs
ihmetyksen aihe on ollut SD:n vaatima virransyöttö, se toimii vain syöttämällä +5
nastaan jossa lukee +3. +5-nastan takana on 3.3 regulaattori, enkä ole vielä keksinyt,
miksei +5 jännitteensyöttö toimi - ei sitten millään. Muistikortteja on kokeilussa
kaksi, SanDiskin ja Kingstonin, eli oletettavasti ihan kelvollisia. Hyvää LC Studion
korteissa on hinta :laughing:

Olen lisäavusta kiitollinen.

joo pitkää sivua tarkotin… jaa-a… vastuksilla ainakin tiputetaan arduinon 5v -> 3.3v, joten jos korttiin on valittu liian pienet vastukset niin teho menee vastuksiin? minkä kokoisia vastuksia levyllä on?

oisko sitten silkkipainatuksessa virhe jos tuo pelaa ristiin. ootko mitannu +5 nastaa että tuleeko sieltä 3.3v?

teg tarkoitti varmaan sitä että kun prossu menee sleep tilaan niin aja 10 11 12 ja 13 LOW tilaan?
mutta entäs jos ne muuttaa inputeiksi? silloin maadotusta ei käsittääkseni vousi tapahtua ion kautta…

Kokeilen kumpaakin juttua (inputeiksi/LOW -tilaan),
kunhan pääsen kotio. Kumma on, jos en saa tätä toimimaan.
Mutta on tässä maailmassa muutakin kummaa.

Koita irroitella prossun i/o piuha kerrallaan, niin selviää missä virta kulkee.

Vaikea irrotella, kun olen tinannut moduulin kiinni painopiiriin.
Tosin olen jo katkonut/tinannut liuskoja moneen kertaan, täytyy
kuitenkin tehdä uusi levy.

Ei toimi sitten millään. Pin 10 Arduinon numeroinnin mukaan
eli SD:n kannalta CS imaisee noi milliampeerit. Jos laitan
ennen sleepiä pinnin inputiksi, niin virta tippuu siedettävään
2.6mA:han, mutta kortille kirjoitus ei toimi. Sleepin jälkeen
laitan pinnin tietenkin output-tilaan, mutta ei auta.

Kysymysmerkki on nyt, mihin ohjelma menee sleepin jälkeen?
Jatkaako rivijärjestyksessä seuraavasta käskystä, jolloin
yritykseni pitäisi toimia? Meneekö loopin alkuun? Vai mihin?

laita se sun koodi tänne ni on helpompi järkeillä? mitä sleep modea käytät?

Pistän copy pastena. Koodissa oleva sleeppikirjasto toimii,
vika ei ole siinä vaan jossain muualla. Koodissa on pätkiä
jotka eivät suoraan kuulu asiaan, mutta ne on kommentoitu
ulos.

#include <DHT.h>

#include <SD.h>
#include <Wire.h>
#include <stdlib.h>
#include <stdio.h>
#include <Sleep_n0m1.h>
#include <DS1307.h>

//#define F_CPU 80000000UL // 8 MHz Crystal osc.

int rtc[7];
#define debugMode 1 // 1 = Serial.print päällä, idleMode sleep
// 0 = Printti pois, pwrDownMode sleep
#define DHTPIN A3 // what pin we’re connected to
#define CSPin 10
#define SDPower 9
#define RTCPowerPin 8 // RTC module power on pin
#define RTCPowerLed 7 // RTC module power indicator
#define tempPin A0

#define DHTTYPE DHT22 // DHT 22 (AM2302)

//#define ldrPin A1 // pin used for LDR

//RTC_DS1307 RTC;
Sd2Card card;
SdVolume volume;
SdFile root;
DHT dht(DHTPIN, DHTTYPE);

Sleep sleep;
int readTemp[55];

static String logDate = “”;
static String diskData="";

const int measurements = 24; // Kuinka monta mittausta ennen lähetystä
float measureIntervalSec = 10; // Measure interval minutes = mittausväli

long sleepTime = 1000*measureIntervalSec; //
int count = 0;

int bytesSent;
boolean sendSMSOK = false;
int ldrOn = 300;

long correctionValue = 2.5;
String tempString = “”;
int tempDataTemperature[measurements];

void isort(int *a, int n) // Sorting function
{
for (int i = 1; i < n; ++i)
{
int j = a[i];
int k;
for (k = i - 1; (k >= 0) && (j < a[k]); k–)
{
a[k + 1] = a[k];
}
a[k + 1] = j;
}
}

void setup()
{
pinMode(CSPin, OUTPUT);
pinMode(SDPower, OUTPUT);
digitalWrite(SDPower, LOW);
pinMode(tempPin, INPUT);
pinMode(RTCPowerPin, OUTPUT);
pinMode(RTCPowerLed, OUTPUT);
digitalWrite(RTCPowerPin, LOW);
digitalWrite(RTCPowerLed, LOW);

if (debugMode==1)
{
Serial.begin(9600);
}
card.init(SPI_QUARTER_SPEED, CSPin);

if (!SD.begin(CSPin))
{
Serial.println(“initialization failed!”);
return;
}
Serial.println(“initialization done.”);
if(SD.exists(“datalog.txt”))
{
SD.remove(“datalog.txt”);
}

analogReference(INTERNAL);

}

long readVcc() {
// Read 1.1V reference against AVcc
// set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(AVR_ATmega32U4) || defined(AVR_ATmega1280) || defined(AVR_ATmega2560)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (AVR_ATtiny24) || defined(AVR_ATtiny44) || defined(AVR_ATtiny84)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (AVR_ATtiny25) || defined(AVR_ATtiny45) || defined(AVR_ATtiny85)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif

delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
long result = (high<<8) | low;
result = 1329782L / result; // Calculate Vcc (in mV); 1125300 = 1.110231000
return result; // Vcc in millivolts
}

void wakeUp() // here the interrupt is handled after wakeup
{
// No operations here
}

int readTemperature_1() // Analog read (LM35)
{
int reading = 0;
float tempC;
for (int i=1; i<=50; i++)
{
readTemp[i] = analogRead(tempPin);
delay(10);
}
isort(readTemp, 50);
reading = readTemp[25];
tempC = reading / 9.31;
tempC = tempC - correctionValue;
return tempC*10;
}

int readTemperature_2() // Digital read (DHT22)
{
int reading = 0;
float tempC;
for (int i=1; i<=25; i++)
{
readTemp[i] = 10 * dht.readTemperature();
delay(10);
}
isort(readTemp, 25);
reading = readTemp[13];
Serial.println(reading);
return reading;
}

int readHumid() // Digital read (DHT22)
{
float h = dht.readHumidity();
//Serial.println(h);
return int(10*h);
}

void loop()
{
//DateTime now = RTC.now();
RTC.get(rtc,true);

String sendRow;
int muunnos;
String temperature;
int temp;
String mittausHEX = “”;
String mark = “-”;
long batteryVcc;
//
// Kerää mittausdata
//
// digitalWrite(10,HIGH);

digitalWrite(RTCPowerPin, HIGH);
digitalWrite(RTCPowerLed, HIGH);
delay(2000);
Serial.println();
logDate = ‘"’+String(rtc[4]);
logDate= logDate+"."+String(rtc[5]);
logDate= logDate+"."+String(rtc[6])+’"’;
logDate= logDate+","+’"’+String(rtc[2]);
logDate= logDate+":"+String(rtc[1])+’"’;
logDate=logDate+",";
logDate=logDate+’"’+String(readTemperature_2());
//String tempString = String(readTemperature_2());
int lenTemp = tempString.length();
//Serial.println(tempString.substring(0,lenTemp-1)+"."+tempString.substring(lenTemp-1,lenTemp));
//logDate=logDate+’"’+tempString.substring(0,lenTemp-1)+"."+tempString.substring(lenTemp-1,lenTemp);
delay(100);
logDate=logDate+’"’;
logDate=logDate+",";
//String humidString = String(readHumid());
logDate=logDate+’"’+String(readHumid());
//Serial.println(humidString);
//int lenHumid=humidString.length();
//Serial.println(humidString.substring(0,lenHumid-1)+"."+humidString.substring(lenHumid-1,lenHumid));
//logDate=logDate+’"’+humidString.substring(0,lenHumid-1)+"."+humidString.substring(lenHumid-1,lenHumid);
delay(100);
//int ldrReading = analogRead(ldrPin);
//Serial.println(ldrReading);

logDate=logDate+’"’;

digitalWrite(SDPower, HIGH);
delay(500);
File dataFile = SD.open(“datalog.txt”, FILE_WRITE);

//if the file is available, write to it:
Serial.println(logDate);

if (dataFile)
{
dataFile.println(logDate);
dataFile.close();
// print to the serial port too:
delay(500);
}
// if the file isn’t open, pop up an error:
else
{
Serial.println(“error opening datalog.txt”);
}
delay(1000);
Serial.print("sleeping ");
Serial.println(sleepTime/1000);
delay(1000); //delay to allow serial to fully print before sleep
digitalWrite(RTCPowerPin, LOW);
digitalWrite(RTCPowerLed, LOW);
digitalWrite(SDPower, LOW);

pinMode(9, INPUT);
//pinMode(10, INPUT);
// pinMode(10, INPUT);
//pinMode(11, INPUT);
//pinMode(12, INPUT);
//pinMode(13, INPUT);

sleep.pwrDownMode(); //set sleep mode
sleep.sleepDelay(sleepTime); //sleep for: sleepTime
delay(200);
pinMode(9, OUTPUT);
pinMode(CSPin, OUTPUT);
digitalWrite(CSPin, LOW);

// pinMode(10, OUTPUT);
Serial.println();

}

jaaa… sulla on functio wakeUp. luulisin että ohjelma menee simne kun sleepistä herää… eikä sen jälkeen tee mitään. kutsu sieltä looppia? en ole tutkinut sen tarkemmin tuota sleeppiä mutta pikaisella googletuksella
The 5 different modes are:
* SLEEP_MODE_IDLE -the least power savings
* SLEEP_MODE_ADC
* SLEEP_MODE_PWR_SAVE
* SLEEP_MODE_STANDBY
* SLEEP_MODE_PWR_DOWN -the most power savings
joten kannattaisi kokeilla myös muita tiloja… kun taidot ei riitä niin kokeillaan :smiley:

Tumppu88

Kiitos avustasi! Sain toimimaan (pwrDown sleeppi vie vain 60uA),
koodiin piti laittaa looppiin muistikortin alustus. Varmaan kytkee
ton kymppipinnin päälle tai jotain. Hyvä näin.

loop()
{
logDate=logDate+’"’;

pinMode(CSPin, OUTPUT);
digitalWrite(SDPower, HIGH);
delay(1000);
card.init(SPI_QUARTER_SPEED, CSPin);

File dataFile = SD.open(“datalog.txt”, FILE_WRITE);

//if the file is available, write to it:
Serial.println(logDate);

if (dataFile)
{
dataFile.println(logDate);
dataFile.close();
// print to the serial port too:
delay(500);
}
// if the file isn’t open, pop up an error:
else
{
Serial.println(“error opening datalog.txt”);
}
Serial.print("sleeping ");
Serial.println(sleepTime/1000);
delay(1000); //delay to allow serial to fully print before sleep
//digitalWrite(RTCPowerPin, LOW);
//digitalWrite(RTCPowerLed, LOW);
digitalWrite(SDPower, LOW);
pinMode(CSPin, INPUT);
sleep.standbyMode();
sleep.sleepDelay(sleepTime); //sleep for: sleepTime
delay(200);
Serial.println();

}