Understanding SD card read sequence in SPI mode - arduino

I'm trying to understand how data is read from an SD card in SPI mode, down to the lowest level (because of an upcoming project of mine).
My setup:
Arduino with SD.h library connected to standard SD card breakout with a logic analyser connected to important pins.
What I know so far:
I went through the initialisation process and I totally understand it now, but when it tries to read I get a little lost;
After the card init is done, the program tries to read from the address 0 with command CMD17: and after this follows some data:
What is weird, is that I could not find what this section of data is representing, it does not appear anywhere in the hexdump of the whole SD card. Only on the second read from the Arduino, at address 0x2000 I get the starting data from the hex dump I'm expecting:
And the beginning of the data packet:
My card is 32G, which is probably SDHC. I should point out that I'm just observing what apparently works and I'm trying to figure out why is that.
My question is, what the data from address 0 meant and why the "start" is at address 0x2000, even if my hexdump shows this data at address 0 (sector 0).

Related

Decode RFID tag Hexadecimal values to Decimal Serial Number

I have around 10k+ devices, each with both a visible serial number printed on a label and a RFID tag from which the serial number can be read as well. My problem is that when I read a RFID tag I get a bunch of hexadecimal values and I am unable to retrieve the actual serial number value from them as it is not a straightforward decimal to hex encoding.
Here are a couple of information that I get when scanning the RFID tag with the Android App "NFC Tools":
- Tag Type: ISO 15693 NXP - ICODE SLIX
- Technology available: NfcV, Ndef
- Serial number: 3C:FB:88:14:50:01:04:E0
- DSFID: 0x00
- Data format: Unknown
- Size: 38 / 106 Bytes
- Writable: Yes
- Can be made Read-only: No
I have noticed that each and every RFID tag contains the same 'header' 50:01:04:E0, so it means there should exist a way to retrieve my serial number from 3C:FB:88:14. In this particular instance, the serial number is 11926214.
I have scanned about 30 units manually, but I would like to avoid having to scan all 10,000 as it is error prone to write down the hex values and the corresponding serial. Is it possible at all with the above information to figure it out ?
Section 9.2.1 of the datasheet for the chip might help
https://www.nxp.com/docs/en/data-sheet/SL2S2002_SL2S2102.pdf
Some App's might show the most significant bit first as it seems with this app (i.e. in reverse to the more normal orientation)
That actually puts 3C:FB:88:14:50 as the IC manufacturer serial number
or 50:14:88:FB:3C as the manufacturer defines it.
I've tried various Hex to Decimal converts like https://www.rapidtables.com/convert/number/hex-to-decimal.html and cannot get any combination and significant bit orientation to convert to the make the device serial number.
These chips also have user defined memory that App's has not been read and the Device Serial could be stored in here and not related to the Tag's serial number. (As the RFID serial is programmed by NXP at manufacture time it is unlikely to also be the devices serial number)
I suggest actually using the App TagInfo by NXP as this is by the Manufacturers of the Chip and can show you the all the raw memory blocks (It can on the card type I use)
BUT it seems that NXP have removed the TagInfo App very recently :-(
Update: Seems you might be able to side load the APK from https://apkpure.com/nfc-taginfo-by-nxp/com.nxp.taginfolite (with the associated risks)
Of course you can use the linked datasheet to write your own App to read the user memory area where the Device Serial might be stored.

Can't get temperature reading out of ble beacon .. at my wits end now. This needs a super-hero I guess

I have a task where I need to read 2 parameters from a BLE Beacon. The documentation was seriously lacking and after a fair amount of effort, I managed to get some basic information about reading the data from the BLE Beacon.
The parameters to read are
1) Battery Voltage of the sensor
2) Temperature the beacon has a built in temperature sensor.
I think I have tried almost every popular Python BLE library out there but I just can't seem to get the temperature reading out of the beacon. "I think" I am able to read the voltage. The reason why I said "I think" is because the value seems to match what was provided in the minimal document. And also when I put the beacon into the charger, I can see the value go up - an indication that it is the voltage reading. As I could not read the temperature ( because the UUIDs that are mentioned in the document, the value doesn't seem to change ). I have tried enabling the sensor in every possible way and method described - by writing 01:00 etc. I spent a fair amount of time to reverse engineer the thing. I ran a packet sniffer and managed to capture the data that was being transferred between the beacon and the mobile app ( They have a mobile app ). But then again I am not able to figure out how the temperature readings are being communicated between the beacon and the app. Let me break the whole stuff in smaller blocks.
Hardware: BLE beacon from which voltage and temperature can be read. The temperature sensor is built into the beacon. And the beacon itself is from Texas Instruments but the temperature, voltage sensing part is done by a third party. They provided us with some minimal information and it was difficult to make sense of some of the sentences as they have trouble communicating in English.
The sequence to get the data goes like this
Scan for beacons
When the beacon is found then connect to it
Enable notification
Set notification interval
Get the voltage and temperature reading.
I have been able to do the first 4 real fast, and "half" of No. 5, i.e getting the voltage part. When I say real fast I mean I got that stuff with nearly no documentation available at that time.
As per the info that I have the data resides in these characteristics/UUIDs. Also please note that the UUID are not standard 128 bit and this caused me issues when using certain libraries. But after some tries I got to read/write to them using handles etc. The handles and other stuff I printed are ones that I read using PYGATT (A Python wrapper for gatttool).
The UUIDs are marked as 1st, 2nd, 3rd and 4th parameters and it has the following to say about the parameters
- A: 1 byte (2nd Param)
- B: Maj + Min values, 4 bytes (4th Param)
- C: 4 bytes (3rd Param)
- D: Enable/disable notification ( I have been able to turn this on )
- E: Set notification interval ( I have been able to set this and can notice the change in notification interval )
This is minimal so as to not have a large file. All it does is this - the mobile app connects to the beacon, then the notifications start and the temperate readings are retrieved by the mobile app. Like I had mentioned, I don't seem to have problem reading the voltage, it's only the temperature that I am getting stuck at. I have been at it for a week now. I think I have tried nearly everything that I could think of. I even enumerated all the writable characteristics and tried writing numbers like 1 ( enables the sensor? ). I could have offered a bounty for this straight away if it were possible. I rarely get stuck for so long with a problem. This is driving me a little crazy. I am getting close to my wits end - I guess it's time for a super hero - anyone out there? :) I can provide for every bit of information needed if someone could indicate what is wrong. I even wrote a cordova app ... and tried a bunch of stuff from my Android phone. I can connect ... write to characteristics, read stuff etc but temperature ready, nah!!! It just won't budge. All I get is the same set of values ( I used a JSON.stringify to display A, B and C). I can bother about the byte order later. I guess that is a smaller problem.
The communication between the beacon and a third party mobile app is fine, it is able to read the temperature info just fine.
I have been looking at wireshark data and I am fairly sure that the temperature data is being communicated at this stage. But then when I decode the "value", it looks like it's the voltage. It mentions l2cap but I am not sure how that is being used here to send the temperature readings ( if it is using that in the first place ).
Update: Wrote to every writable characteristics. Wrote values like 1, 0100, 2, 7 on every writable characteristics. At the same time I was reading every readable characteristic ( in a loop ) and doing a comparison (just true/false) with the previous set of values. This seemed like a quick and easier way to know if something changed. Didn't want to take chances with converting the hex to a float. I can figure out the byte order later.
From the sniffed data (wireshark) I can only see 3 writes happening on the beacon.
I am not fully sure, even after a long discussion, but it seems that the four bytes of the notification are used for the voltage as well as the temperature, since the temperature can most probably be derived from the voltage.
From the values it seems that those four bytes represent the voltage in float (if you ignore the absurd factor of 10^-38 that comes in because only 4 bytes instead of 8 bytes are used).
Since typically the temperature T is derived from a resistivity measurement, where the resistivity R is proportional to the voltage U (if the current is constant), you can in principle calculate the temperature T from the voltage U.
The problem is that T(R) is relatively linear, but not perfectly (in contrast to U(R) which is assumed to be U=RI). So you may need to plot the values for T(U) to find out the curve that they are using.
To add to the confusion, I got the best results when only using the first five bits of the third byte and the eight bits of the fourth byte. I am not aware why this is the case, and it might point to some trouble still.
The best option is to ask for their function T(U) that they are using. If they can and will provide it for you...

Arduino Xbee Shield - Date Translation

I've got two Arduino/Xbees set up over a network and trying to send an analog voltage reading from one to the other. I'm sending the raw integer analog reading across (1-1028 reading) to be translated into a voltage on the second Arduino unit.
So question is - how do I unpack two bytes? I'm using byteHigh and byteLow commands to read the serial value and assembling these two with a Word function, but this isn't working properly. The Word turns out something completely unrelated to the actual analog V sent.
Am I missing something here?

Arduino TinyGPS no data

I am using the TinyGPS library and am trying to display information to get to a specific latitude/longitude via an LCD screen.
I am not getting any data. The output of directionto is "broke" and distanceto and bearingto is 0.
Code redacted
And here is what my pins/hardware look like: http://i.imgur.com/7iDBwxm.jpg
I am using an Arduino Uno, LCD shield and GPS shield by ITead Studio.
I am hoping it is either the pins or not having a GPS signal.
Reddit post: Arduino TinyGPS help
The baud rate for SoftSerial should be 9600.
You need to debug the system step by step to understand where the problem is.
I would start using only the serial monitor and no display.
Please note that when you switch on a GPS that has been moved for several hundred km, and the same is when you switch it on for the first time, may take a while to get the satellites and start giving out some data. Make sure you are in a open area and wait for 5 to 10 minutes before you declare it as "not working". The next time you will switch it on will be much quicker.
I have checked the documentation of your shield and what they also say is to make sure the Micro SD card you use is support SPI mode but not just the SD mode, also don’t forget to format it into FAT16 , and add a “datalog.txt” file on your card for Arduino to log the information.
Try that and then read the data on the sd card to make sure that is logging.
Come back with the outcome of the above tests and we will try to support you further.

Is it stable to change I/O direction on microcontroller repeatedly?

I'm new to microcontroller programming and I have interfaced my microcontroller board to another device that provides a status based on the command send to it but, this status is provided on the same I/O pin that is used to provide data. So basically, I have an 8-bit data line that is used as an output from the microcontroller, but for certain commands I get a status back on one of the data lines if I choose to read it. So I would be required to change the direction of this one line to read the status thus converting this line as an ouput to an input and then back to an output. Is this acceptable programming or will this changing of the I/O pin this frequently cause instability?
Thanks.
There should not be any problem with changing the direction of the I/O line to read the status returned by the peripheral provided that you change the state of the line to an input before the peripheral starts to drive the line and then do not try to drive the line as an output until the peripheral stops driving it. What you must try to avoid is contention between the two driver devices, i.e. having the two ends being driven to opposite states by the processor and peripheral. This would result in, at best a large spike in the power consumption or worse blown pin driver circuitry in the processor, peripheral or both.
You do not say what the processor or peripheral are so I cannot tell whether there are any control bits in the interface that enable the remote device to output the status so that you can know whether the peripheral is driving the line at any time.
I've done this on digital I/O pins without any problems but I'm very far from an expert on this. It probably depends entirely on which microcontroller you are using though.
Yes, it's perfectly fine to change I/O direction on microcontroller repeatedly.
That's the standard method of communicating over open-collector buses such as I2C and the iButton. (see PICList: busses for links to assembly-language code examples).
transmit 0 bit: set output LATx bit to 0, and then set TRISx bit to OUTPUT.
transmit 1 bit: keep output LATx bit at 0, and set TRIS bit to INPUT (let external resistor pull-up line to high)
listen for response from peripheral: keep output LATx bit at 0, and set TRIS bit to INPUT. Let external resistor pull-up line to high when peripheral is transmitting a 1, or let the peripheral pull the line low when peripheral is transmitting a 0. Read the bit from the PORTx pin.
If both ends of the bus correctly follow this protocol (in particular, if neither end actively drives the line to high), then you never have to worry about contention or current spikes.
It`s important to remember that any IO switching in high speed generates EMI.
Depending of switching frequency, board layout and devices sensibilities, this EMI can affect performance and reliability of your application.
If you are having problems in your application use an oscilloscope to check for irradiated EMI in your board lanes.

Resources