Wie gesagt: noch Kleinkram dran zu machen.
Ähäm, naja ... Ich hab's mal im Rahmen der Möglichkeiten für einen Arduino-Uno "Arduinofiziert".
Es lebt tatsächlich, aber im wesentlichen von den Softwarefehlern.
Code:
/*
#include "allpic.h"
#pragma config = 0b000110000100 // hex-datei: fuses des 12F629
#define EE_ROM // eeprom nutzen
#include "pic_mem.h"
#include "timeloop.h" // timer-routinen
*/
// PIC C-Compiler compatibility
typedef int8_t uns8; // stdint compatibility
typedef bool BOOL;
#define FALSE false
#define TRUE false
/*
#define IN_0 0 // GPIO-Eingänge
#define IN_1 1 //
#define IN_2 2 //
#define IN_3 3 //
#define OUT_0 4 // GPIO-Ausgänge
#define OUT_1 5 //
*/
//** alle sensoren, aktoren, triebe und neuronen nach abstraktion gestaffelt ******
#define NUMBEROFNEURONS 30
uns8 zellen[NUMBEROFNEURONS]; // zellen im RAM anlegen
#define FIRE_REQ 7 // fire_req bit in der zelle
#define FIRE_LIMIT 10 // fire_limit
#define SENS_0 0 // spezialzellen definieren
#define SENS_1 1 // Sensoren
#define SENS_2 2
#define SENS_3 3
#define TIMER 4 // Timer-Zelle
#define HUNGER 5 // Hunger-Zelle
#define FIRST_NEURON 6 // davor nur read-only-zellen
#define AKT_0 (sizeof(zellen) - 2)
#define AKT_1 (sizeof(zellen) - 1)
//******* verbunden werden zellen mit vielen links (dendriten) *********
#define NO_LINK -1
//#define MAX_LINKS (128 / sizeof(struct _link))// viele links im EEPROM
#define MAX_LINKS 32
struct _link { // struktur eines EEPROM-links
uns8 src; // leerer link: src_zelle == NO_LINK
uns8 dst; // verbindet source- mit dest-zelle
uns8 use; // nützlichkeit dieses links
};
#define LINK_SRC 0
#define LINK_DST 1
#define LINK_USE 2
/*
uint8_t src;
uint8_t dst;
uint8_t use;
*/
// LINK-Zugriffe im PIC
// #define LINK_RD(a,m) ee_read((a) + offsetof(struct _link,m))
// #define LINK_WR(a,m,v) ee_write((a) + offsetof(struct _link,m),v)
_link Simulated_EEPROM[NUMBEROFNEURONS];
uns8 LINK_RD(uns8 address, uns8 component)
{
uns8 value = 0;
if (component == LINK_SRC) value = Simulated_EEPROM[address].src;
if (component == LINK_DST) value = Simulated_EEPROM[address].dst;
if (component == LINK_USE) value = Simulated_EEPROM[address].use;
return value;
}
void LINK_WR(uns8 address, uns8 component, uns8 value)
{
if (address < NUMBEROFNEURONS)
{
if (component == LINK_SRC) Simulated_EEPROM[address].src = value;
if (component == LINK_DST) Simulated_EEPROM[address].dst = value;
if (component == LINK_USE) Simulated_EEPROM[address].use = value;
} else
{
Serial.print("Error: link address out of range "); Serial.println(address);
delay(100);
}
}
static uns8 rand_link = 0; // randomize link
/*
void gpio_out(uint8_t pin)
{
}
*/
uint16_t FSR; //pointer auf zelle
uint16_t INDF; // ?
static void gi_denke(void) // die genesis
{
uns8 zell_ind = 0, link=0, freeLink=0, buf=0;
BOOL hit;
do { // Suche feuernde zellen
rand_link++; // randomize link
FSR = zellen + zell_ind; // pointer auf zelle
/**** sensoren, aktoren und triebe sind besondere zellen *****/
/*
if (zell_ind <= SENS_3) { // Sensoren abfragen
buf = _BV(zell_ind); // bit-maske entwickeln
if (GPIO & buf) {
if (!(INDF.0)) INDF = FIRE_LIMIT + _BV(FIRE_REQ);
}
else INDF.0 = 0 // FIRE_REQ bearbeiten
} // nun die aktoren
else if (zell_ind == AKT_0) GPIO.OUT_0 = INDF.FIRE_REQ;
else if (zell_ind == AKT_1) GPIO.OUT_1 = INDF.FIRE_REQ;
if (INDF.FIRE_REQ == FALSE) continue; // zelle möchte nicht feuern
*/
/***** wenn zelle feuern will, verfolge die links *************/
// INDF.FIRE_REQ = FALSE; // zelle möchte feuern
INDF &= ~(1 << FIRE_REQ);
freeLink = NO_LINK; link = 0; hit = FALSE;
do { // alle links durchsuchen
rand_link++; // randomize link
buf = LINK_RD(link, LINK_SRC); // linkbyte lesen
if (buf == NO_LINK) freeLink = link; // leeren link merken
else if (buf == zell_ind) { // link gefunden
FSR = zellen + LINK_RD(link, LINK_DST); // pointer auf dst-zelle lesen
//if ((++INDF == FIRE_LIMIT) && (!(INDF.FIRE_REQ))) { // will dst feuern?
if ((++INDF == FIRE_LIMIT) && (!(INDF & (1 << FIRE_REQ)))) { // will dst feuern?
//INDF.FIRE_REQ = TRUE; // feuer_req schon mal vormerken
INDF |= (1 << FIRE_REQ);
buf = LINK_RD(link, LINK_USE); // zwei zellen feuern synchron
LINK_WR(link, LINK_USE, ++buf); // dadurch wird der link nuetzlicher
hit = TRUE; // zumindest ein nützlicher link
}
}
//link += sizeof(struct _link);// nächsten link adressieren
link++;// the link pointer is only an address
} while (link < MAX_LINKS);
//while (link < MAX_LINKS * sizeof(struct _link));
/** wenn kein nützlicher link gefunden und platz ist: erzeuge neuen link **/
if ((!hit) && (freeLink != NO_LINK)) {
LINK_WR(freeLink, LINK_SRC, zell_ind); // link neu erzeugen
buf = rand_link % sizeof(zellen); // randomize verlinken, aber eingrenzen
if (buf < FIRST_NEURON) buf += FIRST_NEURON; // keine read-only-zellen
if (buf == zell_ind) buf++; // zellen nicht direkt rückkoppeln
LINK_WR(freeLink, LINK_DST, buf);
LINK_WR(freeLink, LINK_USE, 0); // ob der link nützlich wird, weiß keiner
}
} while (++zell_ind < sizeof(zellen)); // nächste zelle
}
#define DELETE 0
#define REDUCE 1
#define SLEEP 2
static void gi_links(uns8 steuer) // links abschwächen
{
uns8 link = 0, buf;
do { // alle links durchsuchen
if (LINK_RD(link, LINK_SRC) != NO_LINK) { // gelöschte ignorieren
if (steuer == DELETE) buf = 0;
else {
buf = LINK_RD(link, LINK_USE); // nuetzlichkeit lesen
if (buf) LINK_WR(link, LINK_USE, --buf); // langsam verlernen
}
if (!buf) LINK_WR(link, LINK_SRC, NO_LINK); // link ganz löschen
}
//link += sizeof(struct _link); // nächster link
link++;
} while (link < MAX_LINKS);
//while (link < MAX_LINKS * sizeof(struct _link));
if (steuer == DELETE) rand_link = 0;
}
static void gi_zellen(uns8 steuer)// zell-erregungen abschwächen
{
uns8 zell_ind = 0;
do { // Suche zellen
FSR = zellen + zell_ind; // zellerregung lesen
if (steuer == DELETE) INDF = 0;
if (INDF) INDF--;
if ((steuer == SLEEP) && (INDF > FIRE_LIMIT)) INDF = FIRE_LIMIT - 1;
} while (++zell_ind < sizeof(zellen)); // nächste zelle
}
void showLinks(uint8_t adr)
{
Serial.print(adr); Serial.print(" -");
Serial.print(" src:"); Serial.print(Simulated_EEPROM[adr].src);
Serial.print(" dst:"); Serial.print(Simulated_EEPROM[adr].dst);
Serial.print(" use:"); Serial.print(Simulated_EEPROM[adr].use);
Serial.println();
}
void showAll()
{
Serial.println("list Neurons:");
for (int n = 0; n < MAX_LINKS; n++)
{
showLinks(n);
}
Serial.println();
}
void setup()
{
Serial.begin(115200);
Serial.println("Gugi ;-)");
delay(1000);
gi_links(DELETE); // alle links löschen
gi_zellen(DELETE); // zellerregungen löschen
}
uns8 loopCounter = 0;
// FOREVER {
void loop()
{
Serial.println("gi_denke");
gi_denke();
if (!++loopCounter) {
Serial.println("gi_links");
gi_links(REDUCE); // links langsam verlernen
Serial.println("gi_zellen");
gi_zellen(SLEEP); // schlafen
}
else if (!(loopCounter & 0x1F)) // alle 32 durchläufe
{
Serial.println("gi_zellen");
gi_zellen(REDUCE); // zellerregungen vermindern
showAll();
delay(1000);
}
}
Lesezeichen