In plaats van alle periodieke tabelgegevens handmatig in een programma in de juiste vorm te plaatsen (wat nogal vervelend zou zijn), zou u een programma op uw softwareontwikkelingscomputer kunnen gebruiken om periodiek-tabelgegevensbestanden te lezen en de bijbehorende C- te maken. programmagegevensstructuren.
Het hieronder getoonde pythonprogramma geeft een voorbeeld van die aanpak. (Het bevat een gegevenstabel in een lijst met tupels, dwz leest geen gegevens, maar gegevens zoals die in de tuples kunnen worden gelezen uit een bestand, of met een beetje programmeren, vanuit een < a href = "http://www.meta-synthesis.com/webbook/35_pt/pt_database.php?PT_id=194" rel = "nofollow"> spreadsheet van periodiek-tabelgegevens .)
Het python-programma opent bestand datatables.data.c
voor uitvoer, dan schrijft het C-instructies in dat bestand, die vervolgens kunnen worden toegevoegd aan een schets, datatables.ino
, als later getoond.
Python-programma, densconmelt.py
:
#!/usr/bin/python
# From data as shown in slide 19 of 39 at
# http://www.slideshare.net/bravetiger1964/lecture-11-metals-and-its-alloys-their-crystalline-structure-and-properties
# Physical Properties of several Metals and Alloys.
# Metal or Alloy
# Density (kg/m3)
# Thermal conductivity W/(m*K) (t=20 C)
# Melting point (Tm) (C)
adtm = [
('Aluminum', '2712', '204', '659'),
('Aluminum alloys', '7700-8700', '120-180', '462-671'),
('Brass-casting', '8400-8700', '', '990-1025'),
('Red Brass', '8746', '159', '1027'),
('Yellow Brass', '8470', '115', '930'),
('Bronze - lead', '7700-8700', '', '850-1000'),
('Copper', '8930', '385', '1083'),
('Gold', '19320', '318', '1063'),
('Pure iron', '6800-7800', '72', '1530'),
('Cast Iron', '7850', '', 'Gray 1370, Malleable 1360, White 1370'),
('Wrought Iron', '7750', '58', '1450'),
('Lead', '11340', '35.3', '327'),
('Nickel', '8800', '89', '1453'),
('Silver', '10490', '406', '961'),
('Solder 50/50 Pb/Sn', '8885', '', ''),
('Non-alloyed and low-alloy steel', '7850', '53.6', '1480'),
('Stainless Steel', '7480-8000', '12.11-45.0', '1430-1500'),
('Tin', '7280', '63', '232'),
('Zinc', '7135', '115', '419')
]
locs = []
# To track current offset into datatext, and longest single string part
used = longy = 0
with open('datatables.data.c', 'w') as fo:
fo.write('#ifdef ADDTABLE //Disallows separate compile\n')
fo.write('const char datatext[] PROGMEM = \n ')
for i in adtm:
#a, d, t, m = i
#print '{:20} {:12} {:12} {:12}'.format(a, d, t, m)
for x in i:
locs.append(used)
used += len(x)+1
longy = max(longy, len(x)+1)
fo.write('"{}\\0" '.format(x))
fo.write('\n ')
fo.write(';\nconst int offsets[] = {')
for o in locs:
fo.write(' {},'.format(o))
fo.write(' {}{};\n'.format(used, '}'))
fo.write('enum {} LONGSTR={}, ITEMS={}{};\n'.format('{', longy, len(adtm), '}'))
fo.write('char buffy[LONGSTR];\n')
fo.write('#endif\n')
Let op de lijnen met de opmerkingen die niet zijn opgenomen
#a, d, t, m = i
#print '{:20} {:12} {:12} {:12}'.format(a, d, t, m)
zou een geschikte plaats zijn om het python-programma aan te passen, zodat het uitprint hoe de lijnen eruit zien op het 4x20 LCD-scherm. In plaats van het herhaaldelijk downloaden van bestanden naar uw Uno of Mega om alleen lijnen te corrigeren die een beetje te lang zijn, of niet goed zijn uitgelijnd, enz., Kunt u het Python-programma het uiterlijk van het display laten weergeven in dezelfde lus waarin het gegevensstructuren genereert die moeten worden opgenomen in de Arduino-schets.
Opmerking: als u niet bekend bent met het construct with
, raadpleegt u het gedeelte Met verklaring van pythonforbeginners.com Lezen en schrijven van bestanden op Python pagina.
Wat het Python-programma genereert:
Sommige regels uit het bestand gegenereerd door densconmelt.py
worden hieronder weergegeven, afgewisseld met opmerkingen over wat die regels doen. Later wordt het hele bestand datatables.data.c
weergegeven.
#ifdef ADDTABLE //Disallows separate compile
Die regel is een preprocessor-instructie om te voorkomen dat datatables.data.c
alleen wordt gecompileerd. Tijdens compilaties kopieert de Arduino IDE datatables.ino
en datatables.data.c
naar een tijdelijke werkdirectory en compileert ze allemaal. De body van datatables.data.c
zal echter niet alleen correct compileren (buiten de schets), dus wordt bewaakt voor het veroorzaken van compileerfouten door het te omringen met # ifdef ... #endif
regels.
const char datatext[] PROGMEM =
Die regel vertelt de C-compiler om de waarde van datatext []
op te slaan in het programmageheugen. Het zegt ook dat de waarde en inhoud van datatext
constant zijn, en datatext
een reeks tekens is.
"Aluminum\0" "2712\0" "204\0" "659\0"
"Aluminum alloys\0" "7700-8700\0" "120-180\0" "462-671\0"
"Brass-casting\0" "8400-8700\0" "\0" "990-1025\0"
...
"Tin\0" "7280\0" "63\0" "232\0"
"Zinc\0" "7135\0" "115\0" "419\0"
;
Die lijnen geven elk de naam van een metaal of een legering, de dichtheid, de thermische geleidbaarheid en het smeltpunt. Waarden zijn tekenreeksen in plaats van getallen, dus bereiken en ontbrekende waarden kunnen worden verwerkt. Merk op dat bij regels van C, strings zonder operatoren daartussen aaneenschakelen. Bijvoorbeeld, de regel "Tin \ 0" "7280 \ 0" "63 \ 0" "232 \ 0"
is gelijk aan de regel "Tin \ 07280 \ 063 \ 0232 \ 0 "
. Let op, elke \ 0
is een nul karakter aan het einde van een subtekenreeks. Als de ruimte kort was, kon men alle \ 0
s weglaten en stringlengtes berekenen als verschillen van aangrenzende items in offsets []
.
const int offsets[] = { 0, 9, 14, ... 524, 528, 533, 538, 542, 546};
Die regel vertelt waar elke substring begint, in de grote string datatext
. Deze methode voor het opslaan van offsets en substrings kost 12 bytes per item, dwz 4 · 2 bytes voor 4 int
waarden plus 4 bytes voor null-tekens. Er zijn een vijftal manieren om de overhead te verminderen tot 5 tot 10 bytes per item, maar de meest effectieve eenvoudige wijziging zou zijn om offsets []
in PROGMEM te plaatsen. Bovendien kan een aantal velden van tekenreeksen in gehele getallen of drijvers worden gewijzigd, waarvoor geen nulscheidingstekens of verschuivingswaarden nodig zijn als deze worden geplaatst bij vaste verschuivingen aan de voorzijde van de record van een item.
enum { LONGSTR=38, ITEMS=19};
char buffy[LONGSTR];
#endif
Die lijnen maken twee constanten, LONGSTR en ITEMS, die de lengte van de langste subtekenreeks en het aantal items aangeven; toewijzen van een buffer, zolang de langste subtekenreeks; en sluit de bewaking # ifdef ... # endif
.
datatables.data.c
, shown whole:
#ifdef ADDTABLE //Disallows separate compile
const char datatext[] PROGMEM =
"Aluminum\0" "2712\0" "204\0" "659\0"
"Aluminum alloys\0" "7700-8700\0" "120-180\0" "462-671\0"
"Brass-casting\0" "8400-8700\0" "\0" "990-1025\0"
"Red Brass\0" "8746\0" "159\0" "1027\0"
"Yellow Brass\0" "8470\0" "115\0" "930\0"
"Bronze - lead\0" "7700-8700\0" "\0" "850-1000\0"
"Copper\0" "8930\0" "385\0" "1083\0"
"Gold\0" "19320\0" "318\0" "1063\0"
"Pure iron\0" "6800-7800\0" "72\0" "1530\0"
"Cast Iron\0" "7850\0" "\0" "Gray 1370, Malleable 1360, White 1370\0"
"Wrought Iron\0" "7750\0" "58\0" "1450\0"
"Lead\0" "11340\0" "35.3\0" "327\0"
"Nickel\0" "8800\0" "89\0" "1453\0"
"Silver\0" "10490\0" "406\0" "961\0"
"Solder 50/50 Pb/Sn\0" "8885\0" "\0" "\0"
"Non-alloyed and low-alloy steel\0" "7850\0" "53.6\0" "1480\0"
"Stainless Steel\0" "7480-8000\0" "12.11-45.0\0" "1430-1500\0"
"Tin\0" "7280\0" "63\0" "232\0"
"Zinc\0" "7135\0" "115\0" "419\0"
;
const int offsets[] = { 0, 9, 14, 18, 22, 38, 48, 56, 64, 78, 88, 89, 98, 108, 113, 117, 122, 135, 140, 144, 148, 162, 172, 173, 182, 189, 194, 198, 203, 208, 214, 218, 223, 233, 243, 246, 251, 261, 266, 267, 305, 318, 323, 326, 331, 336, 342, 347, 351, 358, 363, 366, 371, 378, 384, 388, 392, 411, 416, 417, 418, 450, 455, 460, 465, 481, 491, 502, 512, 516, 521, 524, 528, 533, 538, 542, 546};
enum { LONGSTR=38, ITEMS=19};
char buffy[LONGSTR];
#endif
Schets om itemgegevens uit het programmageheugen te halen en weer te geven:
We hebben densconmelt.py
gebruikt om datatables.data.c
te genereren zoals hierboven, en zal nu een schets laten zien die de gegevens van een item uit het programmageheugen haalt en deze toont, wanneer de schets een artikelnummer ontvangt via seriële invoer.
// Sketch that accepts a number via serial input, and responds with
// two lines of data via serial output. The reply-data consists of an
// Alloy name on the first line, and Density, Thermal conductivity,
// and Melting point on the next line.
// See http://arduiniana.org/libraries/streaming/ for Streaming library
#include
// This sets up datatext in PROGMEM; offsets[]; buffy; LONGSTR; ITEMS
#define ADDTABLE
#include "./datatables.data.c"
void setup() {
Serial.begin(115200); //init serial port
}
void loop() {
Serial << "Please enter item number from 1 to " << _DEC(ITEMS) << ": ";
int item = 0;
while (1) {
while (!Serial.available()) {};//Wait for a character
int c = Serial.read();
if (c == '\n') break;
item = 10*item + c - '0';
}
if (item < 1 || item > ITEMS) {
Serial << item << endl << item << " is out of range -- try again.\n";
return;
}
//Display specified item's title on first line
strcpy_P(buffy, datatext + offsets[item*4-4]);
Serial << item << endl << "Item #" << item << ", " << buffy << endl;
//Show other data items on next line
strcpy_P(buffy, datatext + offsets[item*4-3]);
Serial << "Density " << buffy;
strcpy_P(buffy, datatext + offsets[item*4-2]);
Serial << " Thermal cond. " << buffy;
strcpy_P(buffy, datatext + offsets[item*4-1]);
Serial << " [email protected] " << buffy << " C" << endl << endl;
}
Opmerking: voor een beschrijving van strcpy_P()
argumenten, zie nortnu.org's avr/pgmspace.h: Programma Space Utilities pagina.
Zie arduino.cc's PROGMEM -pagina voor een vluchtig overzicht van PROGMEM.
Zie avrfreaks.net's GCC en het PROGMEM-kenmerk pagina voor een gedetailleerde beschrijving van PROGMEM, en zie Nick Gammon's Constante gegevens in programmageheugen plaatsen (PROGMEM) pagina ook.
Voorbeeld van programma-uitvoer, zoals in het vak Seriële Monitor:
Hieronder ziet u een voorbeeld van de uitvoer van het programma zoals weergegeven in het vak Seriële monitor nadat ik verschillende nummers in de invoerregel heb getypt en na elk ingevoerd heb gedrukt. (Opmerking: onder in het vak Seriële monitor stelt u Regeluitgang in op Newline
en gegevenssnelheid op 115200 bps.)
Please enter item number from 1 to 19: 18
Item #18, Tin
Density 7280 Thermal cond. 63 [email protected] 232 C
Please enter item number from 1 to 19: 19
Item #19, Zinc
Density 7135 Thermal cond. 115 [email protected] 419 C
Please enter item number from 1 to 19: 20
20 is out of range -- try again.
Please enter item number from 1 to 19: -2220
-2220 is out of range -- try again.
Please enter item number from 1 to 19: 2
Item #2, Aluminum alloys
Density 7700-8700 Thermal cond. 120-180 [email protected] 462-671 C
Please enter item number from 1 to 19: 0
0 is out of range -- try again.
Please enter item number from 1 to 19: 5
Item #5, Yellow Brass
Density 8470 Thermal cond. 115 [email protected] 930 C
Please enter item number from 1 to 19:
De schets weergalmt het gebruikersinvoeritemnummer twee keer, dus het verschijnt aan het einde van elke invoeraanvraag en op regellabels zoals "Item # 5, Geel Koper".