Webserver ATmega32/644DIP ENC28J60

Gast #727247
Lesenswert?

Ich habe den Thread jetzt so ziemlich durch. Alle Achtung - schönes 
Teil!!!

Was mich noch interessieren würde:
1. Was macht ihr mit Ding - also wofür setzt ihr es ein?
2. Wie sieht es mit dem Stromverbrauch aus - wieviel Leistung zieht das 
Teil?
Gast #727386
Lesenswert?

Die Temperaturmessungen erfolgen mit PT100 in Vierleiterschaltung, Die 
Messschaltung läuft soweit als Prototyp, die Linearisierung erfolgt per 
Software: Beitrag "PT100 Berechnung der Temperatur @ Widerstand"
Bin grade dabei, den Regler zusammenzubauen, darum sind die Wesites auf 
dem Server noch so primitiv.
Wenn das Ganze fertig ist werde ich mich hier melden, da kann der eine 
oder Andere vielleicht auch was mit anfangen. (Geplant: 8 
Temperaturmesstellen, 2 Schaltausgänge 220V, 4 Heizungsmischer => je 2 
Schaltausgänge 220V, 4 PI-Regler => Schaltregler, LC-Display, Webserver 
per I²C oder RS232, Speisung evtl. per Solarpanel und Batterie).
Gast #727414
Lesenswert?

Kurze Zwischenfrage.

Wo bekommt man eigentlich die Buchse für die Stromversorgung her. Bei 
Reichelt und bei Segor ist mit der Suche nach 'SCD-014-A' nichts zu 
finden.
Könnte ich da wohl einen kleinen Tipp bekommen?

Besten Dank im Voraus
Gast #727560
Lesenswert?

Wie sieht es mit dem Stromverbrauch aus?

Und hat evtl. jemand Interesse das Ganze mit einem Mega128 oder CAN128 
aufzubauen? Ich spiele mit dem Gedanken das zu portieren und dann evtl. 
Platinen fertigen zu lassen.

Wie wäre der CP2200 von Silabs als Alternative zum ENC28J60? Der müsste 
etwas schneller sein, denke ich. Klar hat der auch nur 10Mbit/s auf der 
Ethernet-Seite, aber die Kommunikation zum uC sollte durch das parallele 
Interface ne Ecke flotter sein.
Gast #727579
Lesenswert?

>Klar hat der auch nur 10Mbit/s auf der Ethernet-Seite, aber die >Kommunikation 
zum uC sollte durch das parallele Interface ne Ecke flotter >sein.

Also ich habe das Gefühl, dass der so "langsam" ist weil hier nur ein 
TCP-Ping-Pong gespielt wird (geringe Resourcen der AVRs). Es wird immer 
nur eine Nachricht gesendet, erste wenn die Bestätigung kommt wird die 
nächste Nachricht gesendet.

Problem dabei scheint zu sein, dass sich Windows viel Zeit lässt. Mit 
einem Browser unter Linux geht es deutlich schneller.

Es würde wahrscheinlich mehr bringen den Stack etwas zu optimieren, 
statt den CP einzusetzen. Aber der hat vielleicht noch andere Vorteile 
(Energie, Interruptbeslastung, bei UDP gibt es vielleicht auch einen 
Geschwindigkeitsvorteil...).

steffen.
OP Persönliche Seite #727593
Lesenswert?

Hallo,

@Steffen ein schnelleres IC mit parallel Interface bringt nichts, da 
hast du Recht! Eine andere Software schon. Aber dann nur mit mehr RAM 
also gleich wie das Ethernut Projekt. Selbst µIP ist in unseren Fall 
nicht schneller. Benutzt man Linux geht das ganze auch schneller. Ist 
aber evt. auch gut so, vorallem wenn mehrere Leute (Browser) zugreifen.

Mfg
Ulrich
Gast #727626
Lesenswert?

Hallo Thilo,

es bleibt natürlich jedem selbst überlassen was er mit dem WebServer 
macht... IMHO fehlt dem Vorschlag, den WebServer im Internet zu 
betreiben um z.B. Haustechnik damit zu regeln oder auch nur zu 
überwachen, allerdings ein Sicherheitshinweis. Ich würde mir das 2 mal 
überlegen.

Gruß
Sebastian
Gast #727737
Lesenswert?

Hast du natürlich Recht.
Den Türöffner oder Hauptschalter werde ich damit sicher nicht bedienen! 
;)
Soll hauptsächlich zum Ansehen der Parameter sein, Bedienung erfolgt 
dann wohl nur übers LAN daheim.
Gast #727821
Lesenswert?

@Ulrich:

Das war KEINE Kritik irgendwelche Art an der Software!!! Mit den 
Möglichkeiten der verwendeten AVRs (insbes. der Ram-Beschränkung) geht 
das einfach nicht anders.

Vielleicht noch als Hinweis für Mitleser, die nicht so "tief" in der 
Materie stecken:
Beim TCP wird jede Information (Nachricht) bestätigt. Das heisst wenn 
ich eine bestimmte Anzahl an Bytes sende, bekomme ich dafür die 
Bestätigung, dass sie richtig empfangen wurden - wenn nicht, wird nach 
einer bestimmten Zeit die gleiche(!) Information noch mal gesendet. Um 
die Netzlast nun etwas zu verringern, gibt es die Möglichkeit, dass man 
mehrere Pakete auf einmal sendet und auf eine einzelne Bestätigung 
wartet. Dies wäre die Stelle, an der eine Optimierung 
Geschwindigkeitsvorteile bringen würde. Nachteil daran ist, dass der 
Inhalt jedes gesendeten Paketes zwischengespeichert werden muss, damit 
ein neues Senden möglich ist. An dieser Stelle kommt nun der notwendige 
(von Ulrich erwähnte) RAM ins Spiel. Wenn eine Nachricht etwa 500-Byte 
Nutzdaten enthält und der Controller nur 2kByte insgesamt hat, kann man 
es sich nicht leisten, viele Nachrichten zwischenzuspeichern.

dann bis zur nächsten mail,
steffen.
Gast #728040
Lesenswert?

Kann man das Ganze denn noch sicher(er) machen? Es wäre schon von 
Vorteil, wenn man damit auch Einfluss nehmen, d.h. irgendetwas steuern 
könnte...

Wenn ich damit nur aus dem LAN zuhause schalten kann, kann ich die paar 
Meter gerade noch laufen...
OP Persönliche Seite #728143
Lesenswert?

Hallo,

Was heißt nicht sicher?? Wenn ich die IP und Benutzer und Passwort nicht 
weiter gebe halte ich es für sicher genug um seine Heizung zu steuern. 
Allerdings sollte dieses nicht umbedingt aus einem Internetcaffe 
erfolgen. Wer wirklich sicher Steuern und Schalten will benutzt eine 
vorgeschaltete Firewall und einen VPN Server. Mir hat hier noch niemand 
mein Licht an und ausgeschaltet.

Gruss
Ulrich
Gast #728193
Lesenswert?

Ich denke auch, dass der Passwortschutz ausreicht.
Auf meiner HP habe ich ja auch Passwortgeschützte Ordner, dort waren 
auch noch keine illegalen Aktivitäten oder Zugriffe zu verzeichnen.
Und wenn den Domainnamen keiner kennt, wird gar nicht erst probiert zu 
hacken. Außerdem lohnt der Aufwand nicht, hier eine Brutforce-Attacke zu 
starten, nur um jemandem das Licht auszuschalten, oder?
Aber das Passwort/Username noch zusätzlich zu verschlüsseln, da sind der 
Phantasie kaum Grenzen gesetzt ...
Gast #728504
Lesenswert?

Hallo,

also ich sehe das mit der Sicherheit ein bisschen anders. Klar, solange 
es um ein Bastelprojekt geht, kann einem das ziemlich egal sein, aber 
wenn man, wie erwähnt, den AVR webserver ins Internet - oder auch in ein 
Intranet bringt um Messdaten zur verfügung zu stellen oder sogar 
Steuerungsaufgaben davon erledigen lassen will, wäre ich persönlich 
damit ehr vorsichtig.

Username/Passwort:
hält einem "man in the middle attack" nicht stand. Im  Internetcafe oder 
über einen Öffentlichen Hotspot (noch schlimmer) besteht die 
Möglichkeit, dass jemand mithört.

Brutforceattack:
- das rausfinden von passwörtern mittels Wörterbuch - Backtrack CD 
einlegen und los gehts, ist nicht wirklich aufwendig.

Warum sollte jemand bei mir das Licht an und ausschalten wollen:
Im einfachsten Fall aus dem gleichen Grund aus dem Viren geschrieben 
werden und sich der Hund die ... leckt - weil es geht. Und wenn jemand 
erstmal auf den Geschmack gekommen ist, vielleicht schaltet er ja das 
Licht 1000 / Minute an und aus.

SynFlood Attack:
der Webserver ist selbst mit einfachsten mitteln "aus dem Verkehr" zu 
ziehen, steht also nicht mehr zur verfügung.

Keiner kennt meine IP, meinen DNS Namen:
Wenn man sich mal die Logfiles der Firewall ansieht - leider sind die 
meisten billig DSL router nicht gerade gesprächig - kann man 
feststellen, das auch schonmal wahllos drauflos probiert wird. Einem 
Angreifer könnte es ja egal sein bei wem er 1000 mal Lich an und 
ausschaltet, er macht es einfach egal wo.

Mir ist noch nie was passiert:
Ich hatte auch noch nie einen Virus, trotzdem habe ich einen 
Virenscanner im Einsatz.

Firewall & VPN:
yep, das hilft, aber z.B. die Firewall die den AVR vor dem erwähnten 
synflood attack schützt gibt's nicht beim ISP umsonst dazu wenn man 
einen DSL Vertrag abschließt. VPN Geräte bekommt man umsonst garnicht 
(die preiswerteste Variante die ich kenn ist OpenVPN). Um einen 50 EUR 
Webserver zu schützen müßte man dann schon recht tief in die Tasche 
greifen. Außerdem stellt sich dann natürlich die Frage ob ich bei dem 
Aufwand nicht gleich einen "normalen" WebServer installieren sollte.

Ich will das Projekt hier nicht madig machen, sondern lediglich 
aufzeigen welche Probleme sich bei dem "Produktiveinsatz" ergeben 
können. Ob die Sicherheitsrisiken relevant sind oder nicht, muß letzten 
Endes jeder für sich selbst endscheiden.

Gruß
Sebastian
#729008
Lesenswert?

Hi Ulrich.
finde das Projekt sehr interessant!!!
Ich wollte mal fragen ab wann du die enc´s verfügbar hast?

Und ich hab deine LC-Display Platine mal verändert.
Sprich ich hab nur 4x16 LCD´s hier herum liegen.
Werde die Montag ätzen und bestücken
und das Layout dann hier mit Bildern Posten.

MfG
MockUp
Gast #729717
Lesenswert?

Hallo,

@all
Ich verfolge dieses Projekt schon seit längerem mit großem Interesse.
Seit einiger Zeit hab ich den Webserver in der ein wenig modifizierten 
Version 30 am rennen. Nun wollte ich einmal einen mega8 über RS232 
anbinden und übers Web steuern. Auf dem mega8 läuft im großen und ganzen 
die main usart und cmd von Uli.
Ich habe nun ein Problem mit der Kommunikation. Ich sende vom Webserver 
aus z. B. LED1on und möchte dann, dass am mega 8 die entsprechende LED 
angeht. Übers Terminal funktioniert das ganze schon super, nur der 
Webserver und der mega 8 mögen noch nicht so ganz. Ich hatte das 
Problem, dass der Webserver ständig über USART seinen Status abgibt. Der 
mega8 kennt diese Befehle nicht und antwortet mit Error (der Webserver 
antwortet auf den Error mit einem weiteren Error usw. -> 
Endlosschleife). Das hab ich bereits behoben. Allerdings gibt es ein 
Problem, wenn ich in der main das usart_write("Ready\r\n\r\n");) bzw. 
usart_write("ERROR\r\n\r\n"); auskommentiere (im Webserver und mega8). 
Bekannte Befehle wie HELP und ? oder LED1on funktionieren. Sobald ich 
aber einen unbekannten Befehl sende wird dieser zurückgegeben (Echo) und 
ein z.B. HELP oder andere bekannter Befehle funktionieren nicht mehr, 
erst nach einem Reset.
Ich hab die main - while - Schleife auch schon mal auf
1
  while(1)
2
  {
3
      
4
    if (usart_status.usart_ready)
5
    {
6

7
      cmd_exec(&usart_rx_buffer[0]);
8
      usart_status.usart_ready =0;
9
    }
beschränkt. Dann muss ich aber in der LED1on - Funktion irgendein 
usar_write("blablub"); haben sonst wird die LED1on nur ein einziges mal 
ausgeführt.

Also irgendwie hab ich den Eindruck, dass nach dem Empfang eines Strings 
auch ein String ausgegeben werden muss. Aber warum?? Das ist in meinem 
Fall schädlich, da die beiden Controller sonst in einer USART 
Endlosschleife hängen bleiben.

Ich hoffe mir kann jemand helfen. Dank im Voraus.

Stefan

PS: Ist mein erste uC Projekt in C.
Gast #730322
Lesenswert?

Hier für alle die gleich den ganzen Bausatz des Webservers Bestellen 
wollen eine kleine Hilfe um die Bauteile etwas schneller in den 
Warenkorb zu legen als das von Hand möglich ist.

Also viel Spass mit der "OneClick in shopping cart" –Methode

P.S.:  evtl. müsst Ihr in euren Browser JavaScript erlauben
Angehängte Dateien:
Gast #730361
Lesenswert?

Hallo,
mein System läuft jetzt auch. Echt tolles Projekt!
Nur wollte ich jetzt das LCD-Display nach der Schaltung von Ulrich 
anschließen. In der config.h habe ich   "#define USE_SER_LCD    1" 
gesetzt. Aber ich erhalte keine Anzeige.
Hatte aber kein 74AC164N da und habe einen 74HCT164 genommen. Kann es 
daran liegen?

Gruß

Martin
Gast #731364
Lesenswert?

Hallo Ulrich,
da der ATMEGA 644 auch als 20 MHz Version gibt, kann man dann nicht 
statt der festen Busy_Wait Vorgabe folgende Zeile in der lcd.h 
aufnehmen:   #define BUSY_WAIT        0.000375*SYSCLK
?

Gruß
Martin
Persönliche Seite #732217
Lesenswert?

Hallo Leute!

Ich versuche Websiten zu erzeugen, die grösser als
der Buffer sind. Mein 644 arbeitet mit einem MTU von
1600, reicht aber nicht.

Im Moment arbeite ich an einer Anzeige einer Temperaturkurve,
die möglicht viele Werte abbilden soll. Bei 60 dargestellten
Werten funktioniert das ganze noch, hätte aber gerne mehr, türlich :)

SD-Karte zur Speicherung der Webseiten und somit streamen wäre eine 
Idee, jedoch habe ich mich da noch nicht rangetraut :)

Was kann ich tun?

Ansonsten läuft der Webserver super. Inzwischen mit S65-Display
und LM92.

Gruss,
Micha

Hier zu sehen: Temperaturdiagramm mit Javascript
http://mikrocontroller.homedns.org
Persönliche Seite #732271
Lesenswert?

OHA :D

Ich war so in mein Problem verstrickt, habe garnicht
bemerkt, dass Du was völlig anderes meinst ;)

Habe mein Problem nun so gelöst:

Bevor ich den Buffer mit meinen Werten fülle, füge
ich ein Steuerzeichen ein, das einfach den Buffer mit Spaces
voll macht.
Danach habe ich einen fast leeren Buffer, den ich mit Werten füllen 
kann.

Danach wieder füllen mit Spaces bis Anschlag und danach kommt der Rest 
der Seite...


Nicht schön, aber geht :)

gruss,
Micha
Persönliche Seite #732284
Lesenswert?

Ach ja, nochwas:

Da mein Server nicht richtig startet, wenn er per NTP keine Zeit
empfangen hat, habe ich folgendes eingebaut:
1
  NTP_DEBUG("Kein NTP Server gefunden!!\r\n");
2
  
3
  ntp_error++;
4
  if (ntp_error>=10)
5
    {
6
    command_reset();
7
    }
8
  ntp_request();
9
  return;

Dh, er macht nach 10 vergeblichen Versuchen einen automatischen Reset
und versucht es neu.

Gruss,
Micha
Gast #733745
Lesenswert?

Hallo Micha,

wenn die Daten nicht in ein Packet passen wird der Rest doch eigentlich 
automatisch ins nächste Packet gepackt! Wie fügst du denn die aktuellen 
Daten in das Packet ein ? Wenn du die Variablen %VA... in die Seite 
packst, die dann beim kopieren der Daten vom Flash in den Puffer durch 
aktuelle Werte ersetzt werden sollte es eigentlich keine Probleme geben.

Gruss Sascha
_________________________________________________________________
http://sw-penig.dnydns.org:8080/wetter.htm
Gast #734028
Lesenswert?

Habe gestern meine Reichelt Bestellung erhalten.

@Ulrich
Bei der Erstellung von „reichelt.htm“ habe ich mich an deine liste, aus 
dem Worddokument, in deiner Layout-zip gehalten.
1.  R8 ist in eagle aber 2K und in der Liste 2,7K damit auch bei der 
Bestellung
2.  JP1, JP2, JP3 sind laut liste Rastermaß 1,27 -> passen also nicht
 Ist es egal bei R8 ob der Wert 2K oder 2,7K ist?
Bei den JP`s habe ich bei reichelt nur SL 1X36G 2,54 als kleinste 
alternative gefunden mit 0,17€ sogar günstiger als in deiner Liste ;-)

Im Anhang habe ich die geänderte reichelt.htm.
Wenn R8 doch 2K sein soll einfach die  Bestellnummer in 1/4W 2,0K 
ändern.

PS.: kann man die alten reichelt.htm löschen damit nicht neue Leser die 
alten Versionen Verwenden?
Angehängte Dateien:
Persönliche Seite #734141
Lesenswert?

Ts T. wrote:
> Ist ein echt toller Webserver.Laeuft bei mir schon 5 Monate one
> Probleme!!

Dann bist du aber der Zeit mächtig voraus ;)

@Ulrich: Im Datenblatt wird R8 mit 2,32k und 1% Toleranz angegeben. Was 
spricht denn dagegen einen 2,2k Widerstand zu nehmen? Hattest du nicht 
anfangs einen solchen?
2,7k ist weiter weg von 2,32k, als 2,2k. Oder gab es Probleme mit dem 
kleineren Widerstand?

Das einzige "Problem" was ich beobachten kann ist, dass der Strom durch 
den Übertrager steigt und der ENC28j60 ein wenig wärmer wird. Aber 
ansonsten funktioniert mein kleiner Webserver hier ohne Probleme.
Persönliche Seite #734147
Lesenswert?

@Sascha
Die Variablen %VA enthält im original 10 Integer, wenn man alle
nutzt, und in ein HTML einsetzt, hat man max. 10x3=30bytes.
Da reicht der Buffer.

Da ich aber viel mehr Daten darstellen will,
im Moment bin ich bei 2x 120 Messwerten, wären das 2x120x4 = 960 Bytes.
Zusammen mit dem Rest sind das über 1500Bytes, die im Moment der Buffer 
hergibt.

Im Moment probiere ich, eine SD-Karte anzubinden. Dann gibt es das 
Problem
nicht mehr, da dann der Buffer gefüllt wird, wie im Moment die
html-Seiten aus dem Flash.

Schau Dir den Code der Seite mal an, dann siehst Du was ich meine:
http://mikrocontroller.homedns.org/

Gruss,
Micha
Gast #734172
Lesenswert?

oder kann ich die aus dem makefile so verwenden
1
#Fuse settings for ATmega644
2
ifeq ($(MCU), atmega644)
3
  FUSE_BITS = -u -U lfuse:w:0xff:m -U hfuse:w:0xdf:m
4
  HEX_FILE_NAME = MEGA644
5
endif

EXT: FF
HIGH:  df
LOW: ff
Persönliche Seite #734252
Lesenswert?

Michael V. wrote:
> @Thomas
> Hi!
>
> Der Code ist frei verfügbar. Wie Du vielleicht
> gesehen hast, lade ich die library von einem externen
> Webserver nach. Sobald meine MMC-Karte läuft, hole
> ich sie dann von dort.

Naja, so super ist das jetzt auch nicht. Das belegt massig Speicher und 
wenn ich mit meinem Firebug mir das Document-Object-Model anschaue 
brauchts erstmal ne Zeit bis der alle <div>s identifiziert hat ;)

Ich hab aber mit DIVs und Ajax (missbraucht um eine .csv Datei zu laden) 
bereits Balkendiagramme erzeugt.

http://klinkerstein.m-faq.de/JsBarDia/
#735328
Lesenswert?

Hallo,
mit welchem Compiler und mit welchen Einstellungen wurde das kompiliert. 
Ich habe bei avr-gcc folgende Fehlermeldung bekommen:

rm -rf test.o enc28j60.o httpd.o main.o stack.o timer.o usart.o cmd.o 
test.elf dep/* test.hex test.eep test.lss test.map
Build succeeded with 0 Warnings...
avr-gcc.exe -I"C:\Users\user\Desktop\test\..\..\..\..\Program 
Files\Atmel\AVR Tools\include"  -mmcu=atmega32 -Wall -gdwarf-2 
-mmcu=atmega32 -O0 -fsigned-char  -MD -MP -MT test.o -MF dep/test.o.d 
-c  ../test.c
avr-gcc.exe -I"C:\Users\user\Desktop\test\..\..\..\..\Program 
Files\Atmel\AVR Tools\include"  -mmcu=atmega32 -Wall -gdwarf-2 
-mmcu=atmega32 -O0 -fsigned-char  -MD -MP -MT enc28j60.o -MF 
dep/enc28j60.o.d  -c  ../enc28j60.c
../enc28j60.c: In function 'enc28j60Init':
../enc28j60.c:222: error: 'for' loop initial declaration used outside 
C99 mode
make: *** [enc28j60.o] Error 1
Build failed with 1 errors and 0 warnings...
Gast #736250
Lesenswert?

Hallo Ulrich und alle,
ich habe die Ansteuerung des ENC überarbeitet, dürfte deutlich schneller 
sein, da die Bankumschaltung wirklich nur wenn nötig geschieht, also 
nicht bei den gespiegelten Registern:
Beitrag "Re: I/O über Ethernet mit einem ENC28J60"
Beitrag "ENC28J60 correct value of PHLCON and mirrored registers"
Vielleicht will das jemand in dieses Projekt mit einarbeiten.

z.B.
  //config NIC LEDs
  enc28j60PhyWrite(0x14,0x047A);

besser:
  enc28j60_write_phy(ENC28J60_PHY_PHLCON, 0x3472);
//cave: Table3-3: reset value is 0x3422, do not modify the reserved 
"3"!!
//RevA Datasheet page 9: write as '0000', see RevB Datasheet: write 
0011!
#736440
Lesenswert?

Hallo Ulrich,

vielleicht kann ich auch noch etwas zu deinem Projekt beitragen :)

Ich bin gerade auch an einem Projekt mit enc28j60 dran und habe ein paar 
Tricks ausgenutzt um die Datenübertragung schneller hin zu kriegen.
Im Anhang befinden sich die relevanten Codeabschnitte, die ich im 
enc28j60 Treiber geändert habe, damits schneller läuft. Ich bin jetzt 
nicht mehr sicher, wieviel diese Änderung gebracht hat, da ich noch 
einiges anderes am Treiber geschraubt habe. Jedenfalls erreiche ich nun 
bei 20 Mips 420Kb/sek

PC (UDP) --> ENC --> mega644 --> Harddisk

Bei kleinen Paketen(ARP/ICMP) wird der Unterschied warscheinlich nicht 
all zu gross sein, bei grösseren (ab etwa 300 Byte) Frames hingegen 
schon.
Der "originale" Treiber von Pascal Stang macht nach jedem Byte das vom 
Buffer gelesen / geschrieben wird, einen 16bit Vergleich, was das ganze 
ordentlich ausbremst. Ich teile die Daten sozusagen in 256 Byte grosse 
blöcke ein und muss daher nur noch 8bit vergleiche machen...

Gruss
Nik
Angehängte Dateien:
Gast #736637
Lesenswert?

Hi Ulrich,

kleine Kritik :(

In enc28j60.c wird _delay_ms() verwendet. An sich ja nicht
schlimm, aber man muss da höllisch aufpassen.

The maximal possible delay is 262.14 ms / F_CPU in MHz.

Bei 16MHz z.B. darf das delay also maximal 16ms sein.
Sonst gibt es falsche delays. Ich empfehle das Kapitel
zu _delay_ms() in der avrlibc Doku mal zu lesen. Da gibt
es noch ein paar andere Fallen bei _delay_ms().

So könnte man das Problem erstmal entschärfen:

void Delay_ms(unsigned int time)
{
 while(time--) { _delay_ms(1); }
}

Gruß
 Holger
Persönliche Seite #736673
Lesenswert?

Nik Bamert wrote:
> Hallo Ulrich,
>
> vielleicht kann ich auch noch etwas zu deinem Projekt beitragen :)
>
> Ich bin gerade auch an einem Projekt mit enc28j60 dran und habe ein paar
> Tricks ausgenutzt um die Datenübertragung schneller hin zu kriegen.
> Im Anhang befinden sich die relevanten Codeabschnitte, die ich im
> enc28j60 Treiber geändert habe, damits schneller läuft.

Leider hast du die Errata-Workarounds nicht drin, die eProfi vorschlug
Gast #736788
Lesenswert?

Hi Ulrich, klasse Video!

[Kritik] habe gelernt, die Drähte der Bauteile VOR dem Löten 
abzukneifen, um Spannungen und die daraus folgende Whiskerbildung zu 
vermeiden [/Kritik]

Für Bastler nicht unbedingt notwendig, da die Projekte meist nicht für 
Langzeiteinsatz gedacht sind.

Trotzdem: geniales Teil, wird demnächst in meinem Heizungsregler platz 
finden! ;-)
Gast #736819
Lesenswert?

Ist auch bei bleihaltigem Zinn schlimm genug, mit Bleifreiem gibt's ja 
noch keine Langzeiterfahrung.
Wie gesagt, bei Bastlern nicht so tragisch.

Wir haben sehr viele Ausfälle deswegen auf Karten, die so zwischen 20 
und 30 Jahren alt sind.

Das Bleifreie kennen ich noch gar nicht, bin auch nicht besonders scharf 
drauf! ;)
Gast #736838
Lesenswert?

Die Platinen sind meistens doppelseitig. Die meisten Probleme gibt's bei 
dichter Bestückung und unter den Bauteilen (bevorzugt ICs mit 
Keramik-Gehäuse).
Oft sind auch die Drähte umgebogen (maschinelle Bestückung) und berühren 
bei höheren Temperaturen (Wärmeausdehnung) die benachbarte Leiterbahn.

Die kalten Lötstellen gibt's eher bei Produktionsfehlern wie Vibrationen 
bei der Verzinnung oder schlechtenm (billigem) Platinen- und 
Bauteilmaterial. Also nicht zittern beim Löten, vorher 'nen Kurzen 
kippen! ;)
Gast #738135
Lesenswert?

Holla,
@Nik: Du hast Dir zwar viel gedacht, aber ich denke mal, dass Deine Idee 
wenig bringt, denn der Mega kann auch ein paar 16-Bit-Befehle:
addw
cmpw

Man müsste das mal im Assembler-Text anschauen.
und beim  Herabzählen auf 0  braucht man gar keinen expliziten 
Vergleich, denn da wird nur das Z-Flag abgefragt (z.B. bne  branch if 
not equal).

Im Übrigen könnte man Deine Idee auch für Zahlen über 256 realisieren, 
denn die oberen 8 Bits bleiben ja jeweils 256 mal gleich. Aber das 
bringt nur was auf Kernen, die wirklich nur 8-Bit-Befehle haben.

Der Code ist schon ziemlich kompakt, man könnte nur etwas eleganter 
schreiben:
while(len--){
  // write data
  SPDR = *data++
  while(!(SPSR & (1<<SPIF))){};
}

Aber genau so steht es ja in meinem File!

Ich bezweifle jetzt mal, dass Dein Code hier schneller ist.


@Simon K.:
Ich habe überhaupt nichts von den Erratas erwähnt oder vorgeschlagen. 
Aber Du hast recht, so weit ich mich erinnere, sind in Pascals Code die 
Errata noch nicht eingeflossen.


@Ulrich
Aha, Du hast Das .c-File komplett übernommen und nur das .h-File 
angepasst, sehr gut!

Das Video erinnert mich an eine Serie in meiner Kindheit, in der viel 
Handwerkliches gezeigt wurde,  ohne Worte, nur mit Hintergrundmusik.
Was das im WDR? Kennt das noch jemand?



Ich habe gestern mal die ASM-Outputs des Simon-Codes angeschaut, da gibt 
es noch deutliches Optimierungspotential bei den höheren Ebenen.

Oft werden 32-Bit-Variablen mühsam aus Bytes montiert, um dann wieder in 
Bytes zerlegt zu werden. Eigentlich müssten nur 4 Bytes kopiert 
werden...
Persönliche Seite #738155
Lesenswert?

eProfi wrote:
> Holla,
> @Nik: Du hast Dir zwar viel gedacht, aber ich denke mal, dass Deine Idee
> wenig bringt, denn der Mega kann auch ein paar 16-Bit-Befehle:
> addw
> cmpw
>
> Man müsste das mal im Assembler-Text anschauen.
> und beim  Herabzählen auf 0  braucht man gar keinen expliziten
> Vergleich, denn da wird nur das Z-Flag abgefragt (z.B. bne  branch if
> not equal).

Jau, ich glaube ehrlich gesagt auch nicht, dass das arg viel bringt 
(Außer Code-Unübersichtlichkeit ;))

> @Simon K.:
> Ich habe überhaupt nichts von den Erratas erwähnt oder vorgeschlagen.
> Aber Du hast recht, so weit ich mich erinnere, sind in Pascals Code die
> Errata noch nicht eingeflossen.

Nanu, ich beziehe mich auf den von dir verlinkten Thread:
Beitrag "ENC28J60 correct value of PHLCON and mirrored registers"

Und da sind sehrwohl Errata-Workarounds eingearbeitet:
1
  //bad silicon workaround:
2
  //reset tx logic:
3
  enc28j60_spi_write_word(ENC28J60_OP_BFS | ENC28J60_REG_ECON1, (1<<ENC28J60_BIT_TXRST));
4
  enc28j60_spi_write_word(ENC28J60_OP_BFC | ENC28J60_REG_ECON1, (1<<ENC28J60_BIT_TXRST));
(Als Beispiel)

Schaut mal auf der Microchip Homepage, wie riesig das Erratasheet ist...

> Ich habe gestern mal die ASM-Outputs des Simon-Codes angeschaut, da gibt
> es noch deutliches Optimierungspotential bei den höheren Ebenen.

Simon Schulz ist aber gemeint in diesem Falle. Meinen Code dürftest du 
nicht vorliegen haben ;)

> Oft werden 32-Bit-Variablen mühsam aus Bytes montiert, um dann wieder in
> Bytes zerlegt zu werden. Eigentlich müssten nur 4 Bytes kopiert
> werden...

Sicher, dass das überhaupt etwas an Rechenleistung braucht? Ich bin mir 
ziemlich sicher, dass der Compiler hier nur noch die Zugriffsreihenfolge 
in den Speicher beachtet, wenn er Variablen in oder aus Register/n holt.

Wenn Interesse besteht, hänge ich mal meinen Code an. Habe bisher nicht 
viel optimiert muss ich aber auch dazu sagen. Lediglich alle 
(relevanten) Errata-Workarounds sind bisher eingeflossen.
Gast #738218
Lesenswert?

Supi, mein Server läuft auch. Respekt und Dank an dieser Stelle!

Ein Problem nur mit dyndns:

dynamic-DNS-Account mit Router-IP eingerichtet, im Router DDNS und 
Portforwarding (Port 80 TCP&UDP) aktiviert. Wenn ich nun meine 
dyndns-URL aufrufe, meldet in stack.c die Funktion check_packet() 
"Erzeuge ARP Reply" über die DEBUG-Ausgabe - mehr passiert nicht.
Provider ist Kabel-Deutschland.

Was mach ich falsch oder wieso klappt es nur im lokalen Netz?
Gast #738420
Lesenswert?

@ eProfi und Simon K.

Ich hab die Idee von Nik Bamert mal in meinen Code einfliessen lassen 
(leicht geaendert , da man den code von nik auch noch optimieren 
koennte) und habe es getestet.

100 Byte Udp Echo x 1000 wiederholungen

-> ca 8,5 % schneller bei mir
Gast #738488
Lesenswert?

Ich hätte da auch einen Vorschlag zur Optimierung.
Hier mal für enc28j60_write_buffer()

Die Originalschleife ergibt folgenden Code

   while(len--){
  SPDR = *buffer++;
  while(!(SPSR & (1<<SPIF)));
    }

Das ASM Listing:

  while(len--){
    //send data
    SPDR = *buffer++;
    4e90:  80 81         ld  r24, Z
    4e92:  8e bd         out  0x2e, r24  ; 46
    while(!(SPSR & (1<<SPIF)));
    4e94:  0d b4         in  r0, 0x2d  ; 45
    4e96:  07 fe         sbrs  r0, 7
    4e98:  fd cf         rjmp  .-6        ;
    4e9a:  31 96         adiw  r30, 0x01  ; 1
    4e9c:  61 50         subi  r22, 0x01  ; 1
    4e9e:  70 40         sbci  r23, 0x00  ; 0
    4ea0:  8f ef         ldi  r24, 0xFF  ; 255
    4ea2:  6f 3f         cpi  r22, 0xFF  ; 255
    4ea4:  78 07         cpc  r23, r24
    4ea6:  a1 f7         brne  .-24       ; 0x4e90


Eine do Schleife ergibt viel besseren Code:

  do{
    SPDR = *buffer++;
    len--;
    while(!(SPSR & (1<<SPIF)));
  }while(len);


Das ASM Listing:

  do{
    //send data
    SPDR = *buffer++;
    4e8e:  81 91         ld  r24, Z+
    4e90:  8e bd         out  0x2e, r24  ; 46
    len--;
    4e92:  61 50         subi  r22, 0x01  ; 1
    4e94:  70 40         sbci  r23, 0x00  ; 0
    while(!(SPSR & (1<<SPIF)));
    4e96:  0d b4         in  r0, 0x2d  ; 45
    4e98:  07 fe         sbrs  r0, 7
    4e9a:  fd cf         rjmp  .-6        ; 0x4e96
          } while(len);
    4e9c:  61 15         cp  r22, r1
    4e9e:  71 05         cpc  r23, r1
    4ea0:  b1 f7         brne  .-20       ; 0x4e8e


Die Schleife enthält schon mal zwei Befehle weniger.
Das beste ist aber, das zwei Befehle schon ausgeführt werden
während das SPI Modul noch am shiften ist.

Gruß
 Holger
Gast #738499
Lesenswert?

Nochmal zu dyndns von 4 Postings weiter oben:

Ich habe IP 91.65.221.64 genommen, die dyndns ermittelt hat, die 
gleiche, wie sie auch z.B. www.myip.ch anzeigt. Ist doch die Richtige, 
oder? Oder was ist die IP vom lokalen Netz?
Hier ein Auszug aus der Status-Page des Routers:

Geräteinformation:

LAN
MAC-Adresse  00-15-E9-E3-56-5F
IP-Adresse  192.168.0.1
Subnetzmaske  255.255.255.0
DHCP-Server  Aktiviert

WAN
MAC-Adresse  00-15-E9-E3-56-5E
Verbindung    DHCP Verbundener Client.

Verbleibende Lease-Time  00:50:05
IP-Adresse  91.65.221.64
Subnetzmaske  255.255.254.0
Gateway  91.65.221.254
Domain Name Server  83.169.184.33, 83.169.184.97

Danke & Gruß Frank
Gast #738604
Lesenswert?

@ Frank

für die Beantwortung externe Anfragen braucht dein WEB-Server die IP des 
Router's nicht zu wissen, denn der Router fragt ja per ARP in dein 
lokales Netz wo sich das Gerät mit der im Portforwarding eingerichteten 
lokalen Adresse befindet.
Bei mir funktioniert allerdings auch keine Anfrage aus dem lokalen Netz 
an meine öffentliche IP - irgendwas scheint der Router (T631) da nicht 
richtig zu händeln!?

Wenn ich den externen Seitenabruf meines WEB-Servers testen will, gehe 
ich immer über einen externen Proxy (z.B. über JAP).

Sascha
______________________________________________
http://sw-penig.dyndns.org:8080/wetter.htm
Gast #738617
Lesenswert?

Hi,

hier könnte man noch etwas Zeit schinden:

void enc28j60_send_packet(unsigned int len, unsigned char *buffer)
{
  unsigned int tmp;
  //still sending ?
  //wait max 50*10 = 500ms:
  for(tmp=0; tmp<500; tmp++){
    if (!(enc28j60_read_address(ENC28J60_REG_ECON1) & 
(1<<ENC28J60_BIT_TXRTS))){
      //send finished -> tx packet
      break;
    }
    //tx not finished yet, wait 10ms
    _delay_ms(1);
  }

Warum 10ms warten wenn man auch nur 1ms warten kann ;)

Und hier mal eine Senderoutine zum nachdenken:

 SPDR = *buffer++;
 len--;

 unsigned char by;

 do
  {
   by = *buffer++;
   len--;
   while(!(SPSR & (1<<SPIF)));
   SPDR = by;
  }while(len);

 while(!(SPSR & (1<<SPIF)));

Schneller dürfte es kaum noch gehen. Der größte
Teil der Schleife wird ausgeführt während das
SPI Modul noch am schieben ist.

Gruß
 Holger
Gast #738629
Lesenswert?

@ Holger

    warum nicht gleich in ASM

    hier mal mit den Registern aus deinem Posting weiter oben ...

//    len = r22,r23
//    *buffer = Z



    subi    r22,0x01
    suci    r23,0x00    ;len--   //wg. Abruchbedingung
loop:
    ld      r24,Z+      ;temp=*buffer++
wait:
    in      r0, 0x2d
    sbrs    r0, 7
    rjmp    wait        ;while(!(SPSR & (1<<SPIF)))
    out     0x2e, r24   ;SPDR = temp
    subi    r22, 0x01
    sbci    r23, 0x00
    brcc    loop        ;while(len--) //!Abruch der Schleife bei -1

-> erledigt alles innerhalb der der SPI-Ausführungszeit

Gruss
Sascha
Gast #738633
Lesenswert?

>Bei mir funktioniert allerdings auch keine Anfrage aus dem lokalen Netz
>an meine öffentliche IP - irgendwas scheint der Router (T631) da nicht
>richtig zu händeln!?

Das hatten wir mal in einem anderen Thread. Das Thema war das gleiche.
Damals war es aber AFAIR ein AVM-Router.
Vielleicht liegt es an der DYNDNS-Freigabe im Router...
Gast #738650
Lesenswert?

@ sascha

>    warum nicht gleich in ASM

Wozu ?
Das hat der Compiler draus gemacht:

 SPDR = *buffer++;
    4e8c:  f9 01         movw  r30, r18
    4e8e:  81 91         ld  r24, Z+
    4e90:  8e bd         out  0x2e, r24  ; 46
    4e92:  62 0f         add  r22, r18
    4e94:  73 1f         adc  r23, r19
 len--;

 unsigned char by;

 do
  {
   by = *buffer++;
    4e96:  21 91         ld  r18, Z+
   len--;
   while(!(SPSR & (1<<SPIF)));
    4e98:  0d b4         in  r0, 0x2d  ; 45
    4e9a:  07 fe         sbrs  r0, 7
    4e9c:  fd cf         rjmp  .-6        ; 0x4e98
    SPDR = by;
    4e9e:  2e bd         out  0x2e, r18  ; 46
  }while(len);
    4ea0:  e6 17         cp  r30, r22
    4ea2:  f7 07         cpc  r31, r23
    4ea4:  c1 f7         brne  .-16       ; 0x4e96



while(!(SPSR & (1<<SPIF)));
    4ea6:  0d b4         in  r0, 0x2d  ; 45
    4ea8:  07 fe         sbrs  r0, 7
    4eaa:  fd cf         rjmp  .-6        ; 0x4ea6

Sieht doch perfekt aus.
 Holger
Gast #738685
Lesenswert?

@ Holger

Ja den buffer-Pointer als Abbruchbedingung zu verwenden ist auch ne 
Möglichkeit. Kürzer u. schneller wird's nun auf keinen Fall mehr - 
ausser bei den keineren ATMega-Typen, da ist das SPSR noch im Bereich wo 
ein direktes prüfen des Bit's im IO-Reg. möglich ist - aber das weiß der 
Compiler auch!



@ STK500-Besitzer

im T631 steckt auch Hardware von AVM - am DYNDNS kann's nicht liegen, 
denn der T631 hat keine DYNDNS-Client.

Gruss
Sascha
Gast #738725
Lesenswert?

dyndns-klappt jetzt:

Zumindest bei mir (Router D-Link DI-524) hing es einfach am MAC-Filter 
"Nur Computern mit den aufgelisteten MAC-Adressen ist der Zugriff 
erlaubt", in dem musste ich den AVR-Server noch eintragen....
Gast #738866
Lesenswert?

@ Simon K.

>Es ist aber problematisch, wenn man erst auf das Interruptbit wartet und
>dann ne SPI-Sendung losschickt.

Stimmt, aber ich denke du hast das

 SPDR = *buffer++;

oben über der Schleife übersehen. Das ist die erste Sendung
bevor das Interruptbit abgefragt wird. Nur deshalb funktioniert
die Schleife überhaupt.

Ich sagte ja: Man muss ein wenig drüber nachdenken ;)

Gruß
 Holger
Persönliche Seite #738877
Lesenswert?

holger wrote:
> @ Simon K.
>
>>Es ist aber problematisch, wenn man erst auf das Interruptbit wartet und
>>dann ne SPI-Sendung losschickt.
>
> Stimmt, aber ich denke du hast das
>
>  SPDR = *buffer++;
>
> oben über der Schleife übersehen. Das ist die erste Sendung
> bevor das Interruptbit abgefragt wird. Nur deshalb funktioniert
> die Schleife überhaupt.

In dem Post mit dem Assembler-Listing? Habs gerade gesehen :D
Gast #739011
Lesenswert?

Moin,

hier noch eine optimale Leseschleife für enc28j60_read_buffer()

  //read data & store in buffer:
   unsigned char by;

  SPDR = 0x00;
        len--;

   do
    {
    while(!(SPSR & (1<<SPIF)));
       by=SPDR;
    SPDR = 0x00;
       *buffer++ = by;
       len--;
    }while(len);

  while(!(SPSR & (1<<SPIF)));
        *buffer = SPDR;


Prinzip genau wie bei der Schreibschleife aus meinem obigen Posting.
Beitrag "Re: Webserver ATmega32/644DIP ENC28J60"

Der größte Teil der Schleife wird abgearbeitet während das SPI
Modul noch am schieben ist.

Schluß mit dem trödeln ;)
 Holger
Gast #740516
Lesenswert?

@ Dirk
>die diskussion zum SPI-Speed hatten wir 2006 schon mal gehabt und hatten
>auch Code entwickelt. Interessant ist auch der Link im Beitrag selbst,
>wo der Code analysiert wird, an realen übertragungen.

Hi Dirk,

ich teste meine Codes an realen Übertragungen ;)

Hier mal ein paar Messergebnisse für enc28j60_write_buffer();
Gemessen bei 16MHz CPU Takt und ungefähr 1300 Bytes pro buffer.

Die Originalroutine mit while(len--)
     3.0ms

Meine erste verbesserte Version mit do{}while(len);
     2.4ms

Meine letzte optimierte Version
     2.0ms

Deine Codes sehen meinen schon recht ähnlich.
Da waren wohl die gleichen Gedankengänge am Werk.
Beim WinAVR ist es oft besser fußgesteuerte do{}while();
Schleifen zu verwenden wenn es geht. Der Schleifenzähler
sollte dabei auch runterzählen.

Das bringt aber nicht immer was. Da muss man ein bißchen
rumprobieren und öfter mal ins ASM-Listing schauen.

Ich hab auch schon mit Schleifen rumprobiert die
SPIF gar nicht mehr abfragen. Einfach mit genügend
NOP auffüllen. Da tritt einem aber der Compiler
oft in den Hintern weil er an den Schleifen
rumoptimiert. Am sinvollsten wäre wohl irgendwas mit
Inline Assembler. Aber dazu bin ich zu faul :(


Gruß
 holger
#741799
Lesenswert?

Hallo an alle,

in verfolge den Thread schon von anfang an und habe schon mehrere 
Softwareversionen erfolgreich ausprobiert. Respekt, es ist ein 
supergeiles Project und genau das, was ich schon die ganze Zeit gesucht 
habe. Mein erster Webserver auf Basis des ENC28J60 war der von 
tuxgraphics, hat auch funktioniert, aber der Stack kann ja nur ein 
Packet zurücksenden und das war dann für meine Website etwas zu wenig.

Nun zu meiner Frage. Ich möchte den Webserver dazu verwenden, um 
Schaltfunktionen auf anderen Controllern auszuführen und dann den Status 
der entsprechenden Ports auch zurücklesen zu können. Das heißt, das der 
Mega32 mit der Webserverapplication quasi der Master ist, der die 
Anbindung an das Ethernet ermöglicht und an ihm hängen dann die anderen 
Controller als Slave für die entsprechenden Schaltfunktionen.
Nun ergibt sich allerdings das Problem, wie die Kommmunikation der 
Controller untereinander am besten zu realisieren ist. Mein erster 
Gedanke wahr natürlich die SPI, aber die spricht ja schon mit dem ENC 
und ich bin mir nicht sicher, ob ich da ohne Probleme noch weitere 
Controller mit ranhängen kann (EMV, Leitungslängen u.s.w.). Zu welchen 
Kommunikationssystem würdet ihr mir raten?

Viele Grüße
Torsten
Gast #741856
Lesenswert?

Wenn du die serielle Schnittstelle nicht für printf o. ä. benötigst, 
kannst du auch diese verwenden. Sollte schnell und einfach zu machen 
sein. Wenn du eine strenge Master-Client Kommunikation aufbaust, können 
dann auch mehrere Teilnehmer kommunizieren.

Steffen.
(Firma: www.ags.tu-bs.de) #741882
Lesenswert?

Moin,
ist das eigentlich normal ,dass der Bildaufbau der Kamera bei 320x240 
pixeln
etwa 40 Sekunden dauert?? Oder kann man da irgendwo noch was an der 
Baudrate rumschrauben? Ich verwende den Atmega 644. Natürlich erwarte 
ich keine 10 Frames/s. Mir ist klar, dass der Avr daran ganz schön zu 
knabbern hat, aber dass er solange braucht hätte ich nicht gedacht.

Grüße Henning
OP Persönliche Seite #741885
Lesenswert?

Hallo,

Der Bildaufbau dauert unter Windows 50Sek. unter Linux 10Sek das ist 
schon richtig! Das liegt daran das auf ein ACK vom Rechner gewartet 
wird. Bei Windows kann das gute 500ms dauern. Wie man es beschleunigen 
kann? Einfach einen Mega644 nehmen und in Stack.h die Packetsize von 600 
auf 1400 setzen (Zeile76). Desweiteren in cam.h DAT_BUFFER_SIZE auf 1400 
(Zeile22). Schon wird das Bild in 10Sek unter Windows geladen  (Linux 
noch schneller).

Gruß
Uli
Gast #741942
Lesenswert?

Hallo!
Kann mir vielleicht einer sagen wie ich diese Fehlermeldung wegbekomme ?
1
httpd.o: In function `httpd_header_check':
2
httpd.c:158: undefined reference to `strcasestr_P'
3
httpd.c:159: undefined reference to `strcasestr_P'
4
httpd.c:160: undefined reference to `strcasestr_P'
5
httpd.c:183: undefined reference to `strcasestr'
6
httpd.c:189: undefined reference to `strcasestr'
7
httpd.c:200: undefined reference to `strcasestr'
8
\newStack1_0_43/httpd.c:204: undefined reference to `strcasestr'

Schonmal vielen Dank!
Gast #742096
Lesenswert?

Hallo
habe aus einem alten Projekt nen Code, der sich meineserachtens sehr 
einfach in den des Webservers integrieren lässt. Hierbei handelt es sich 
um das Auslesen des ds1621 Temperatursensors.
Ich hab ihn jetzt auf das Mindeste gekürzt. Nur weiß ich jetzt nicht, 
wie ich das mit den Timern machen soll, da ich mich mit denen nicht so 
richtig auskenne. Im Prinzip muss das I2C_delay auf den Timer vom 
Webserver angepasst werden.

Hat einer ne Idee


Grüße Henning
Gast #742409
Lesenswert?

Hallo,
ich habe Probleme mit der neuen Version 1.0.43. Ich betreibe das System 
mit dem 644 und mit der Taktfrequenz 14.7456MHz. Ohne LCD Display 
erhalte ich über die RS232 folgende Ausgabe:
System Ready
NIC init:
danach nichts mehr. Selbst über ein Ping ist er nicht erreichbar!
Wenn ich das LCD-Display aktiviere erhalte ich weder eine Anzeige noch 
eine Ausgabe über die RS232:
Mit den alten Version 1.0.40 klappt alles. Muss ich noch etwas 
zusätzlich ändern?

Gruß
Martin
Gast #742464
Lesenswert?

Hallo Uli,
leider finde ich die angeführten Stellen nicht im Quelltext. Du meinst 
doch die "enc28j60_Init" in der enc28j60.c! Aber da und auch wo anders 
finde kein delay_us.
Ich benutze das Layout von Henning mit dem Magjack!
Gruß
Martin
(Firma: www.ags.tu-bs.de) #742484
Lesenswert?

Hallo Martin,
eigentlich müsste das funktionieren, hab 3 meiner Boards mit der neusten 
Version am laufen. Hast du nochmal den Aufbau und die Lötstellen 
überbrüft?  (Drahtbrücken für die Spannungsversorgung vom ENC drin???)
oder in der config.h richtige Taktfrequenz??


Grüße Henning
Gast #742501
Lesenswert?

Hallo Henning,
ja alle Brücken sind drinnen. Das Board klappt ja mit der Version 
1.0.40! Auch die Taktfrequenz ist richtig eingestellt.
Sind mit der neuen Version evtl. die Bauteil Toleranzen bei bestimmten 
Teilen kritischer?

Gruß
Martin
Gast #742537
Lesenswert?

Hallo,
vielen Dank für die Hilfen. Konnte den Fehler nicht finden. Nach dem bei 
meinen Board von Ulrich die Version auch nicht funktionierte habe ich 
noch einmal den Quellcode geladen und auf die IP-Adressen angepasst. 
Jetzt klappt es! Bei der ersten Anpassung muss mir irgendwo ein Fehler 
unterlaufen sein.
So jetzt werde ich versuchen die Kamera anzusteuern.

Gruß
Martin
(Firma: www.ags.tu-bs.de) #742563
Lesenswert?

Hallo Martin,
gut, dass Du das eben nochmal geschrieben hast, dass es läuft. Wollte 
grad mal exakt Deinen Aufbau testen. Sprich 14,7456Mhz ohne Kamera und 
ohne Display mit jungfräulichem Code. Weil meine Aufbauten laufen ja 
fast alle mit 16Mhz und mega 32, bis auf den einen mit nem 644 und 
Kamera
(Firma: www.ags.tu-bs.de) #742733
Lesenswert?

Hallo Ulrich,
ich hab da eine kleine Anregung für die nächste Version des Layouts.
Man könnte per Jumper Versorgungsspannung auf den D-Sub geben. Dann muss 
nur an der Max232 Fassung gebrückt werden (oder hier auch Jumper) und 
man könnte die Kamera an den D-Sub anschließen. Oder man führt RX/TX 
noch hinten mit auf dem Wannenstecker raus.

Grüße Henning
Gast #742800
Lesenswert?

Hallo,

habe das mit dem Wertebereich der Variable für die Servoposition noch 
nicht ganz begriffen

volatile unsigned char servo_pos;// min = 28/1ms max = 56/2ms


was ist hiermit gemeint?:
// min = 28/1ms max = 56/2ms

Kann mir da jemand genaueres zu sagen?
evntl. mit Beispiel

danke schonmal

Günni
Gast #742810
Lesenswert?

Also heisst, wenn er bis zum rechten Anschlag drehen soll

servo_pos = 28;
servo_go_pos();

und wenn er bis zum bis zum linken Anschlag drehen soll:

servo_pos = 56;
servo_go_pos();

????

und was ist dann mit servo_pos = 0; ?? das soll doch eigentlich die 
mittelstellung sein, oder?
Gast #742861
Lesenswert?

Hallo, habe das Servo nur zum Test ganz Primitiv eingebunden:
1
if(strcasestr_P((char*)&eth_buffer[a],PSTR("LED3=3"))!=0){tmp |=(1<<PA2);}
2
          if(strcasestr_P((char*)&eth_buffer[a],PSTR("LED4=4"))!=0){tmp |=(1<<PA3);}
3
          if(strcasestr_P((char*)&eth_buffer[a],PSTR("LED5=5"))!=0){tmp |=(1<<PA4);}
4
          if(strcasestr_P((char*)&eth_buffer[a],PSTR("LED6=6"))!=0){tmp |=(1<<PA5);}
5
          if(strcasestr_P((char*)&eth_buffer[a],PSTR("LED7=7"))!=0)
6
                    {
7
                    tmp |=(1<<PA6);
8
                    servo_pos = 29;
9
                    servo_go_pos();
10
                    }

Nun passiert folgendes: Sobals man die Checkbox markiert hat und auf 
Senden klickt, bewegt sich das Servo um 2-3° und dann stürzt der ganze 
Server ab.

Woran kann das liegen??

Grüße
Gast #742885
Lesenswert?

>Nun passiert folgendes: Sobals man die Checkbox markiert hat und auf
>Senden klickt, bewegt sich das Servo um 2-3° und dann stürzt der ganze
>Server ab.
>Woran kann das liegen??

Netzteil zu schlapp ?
Gast #743076
Lesenswert?

Hi Ulrich,

ich hab da eine unschöne Stelle im httpd gefunden.
In http_data_send()

 b = ((*http_entry[index].new_page_pointer+3)-48)*10;

oder genauer nur dies hier

 *http_entry[index].new_page_pointer+3

Da scheint es nicht eindeutig zu sein was der Compiler
zuerst machen soll. Erst den Pointer + 3 und dann
den Wert aus dem Speicher holen, oder erst den Wert
aus dem Speicher holen und DIESEN dann + 3.
WinAVR macht es so wie geplant. WinARM bevorzugt
Methode 2 und prompt geht es schief.

Zwei Klammern mehr und alles ist eindeutig:

 b = ((*(http_entry[index].new_page_pointer+3))-48)*10;


Achso, und das hier ist auch nicht schön.
Auch in http_data_send()

char var_conversion_buffer[10];

str_len = strnlen(var_conversion_buffer,MAX_VAR_ARRAY);

MAX_VAR_ARRAY ist glaub ich für was anderes gedacht ;)


Gruß
 Holger
Persönliche Seite #743086
Lesenswert?

holger wrote:
> Hi Ulrich,
>
> ich hab da eine unschöne Stelle im httpd gefunden.
> In http_data_send()
>
>  b = ((*http_entry[index].new_page_pointer+3)-48)*10;
>
> oder genauer nur dies hier
>
>  *http_entry[index].new_page_pointer+3
>
> Zwei Klammern mehr und alles ist eindeutig:
>
>  b = ((*(http_entry[index].new_page_pointer+3))-48)*10;

Also ich versteh euch nicht. Wenn ich so eine Funktionalität ausdrücken 
will in einer Code-Zeile, dann setze ich doch erstmal überall da 
klammern, wo es beim hinsehen  nicht eindeutig lesbar ist, was zuerst 
ausgeführt wird. So geht man auch sicher, dass der Compiler genau das 
macht, was man selber meint.

Wieso macht ihr sowas ohne Klammern? Probiert ihr das aus? Macht ihr das 
erst mit Klammern und probiert anschließend aus, obs auch ohne klappt? 
Oder guckt ihr jedes mal in das Compilerhandbuch, welche Operation 
zuerst ausgeführt wird und überlegt euch dann wo (keine) Klammern 
hinsollen?

Also ich wähle ganz klar erstere Variante, die ist 1. sicherer und 2. 
besser lesbarer.
Gast #743097
Lesenswert?

>Die Stelle konnte ich nicht finden:
>b = ((*http_entry[index].new_page_pointer+3)-48)*10;

Upps, kannst du ja auch nicht. Ist ja nicht dein Originalcode.
Den Fehler hab ich mir selber eingebrockt.

Entschuldigung bitte für die Falschmeldung :(

Beim nächsten mal pass Ich besser auf.
Holger
(Firma: www.ags.tu-bs.de) #743297
Lesenswert?

Hallo,
kann es sein, dass irgendwas mit dem Servo-Timer noch nicht stimmt??
Mein Servo bewegt sich nur in einem ganz kleinem Winkel (~5°) von 28 
nach 56
Die Zeit zwischen den beiden Befehlen ist aber ausreichend.
Habe Atmega644 @ 14,7456Mhz und benutze Version 46
Grüße Henning
Gast #743414
Lesenswert?

Hallo, ich weiß nichtmehr weiter, es scheitert immer an den einfachsten 
Sachen.
Folgendes: Die If Anweisung wird durchgeführt, aber Hinterher führt er 
auch noch die Else Anweisung durch . Ist doch irgendwie komisch, oder? 
Macht der Compiler da irgendwas komisches draus?
1
          if(strcasestr_P((char*)&eth_buffer[a],PSTR("LED7=7"))!=0){tmp |=(1<<PA6);}
2
                    if(strcasestr_P((char*)&eth_buffer[a],PSTR("LED8=8"))!=0)
3
                    {
4
                    tmp |=(1<<PA7);
5
                    servo_pos = 255;
6
                    servo_go_pos();
7
                    }
8
                    else
9
                    {
10
                    servo_pos = 0;
11
                    servo_go_pos();
12
                    }

Kann mir jemand weiterhelfen??

Grüße
Gast #744154
Lesenswert?

Hi Ulrich,

ich hätte da mal wieder einen Vorschlag :(

arp_timer_call(); verbrät unnötig Rechenzeit im Timerint.
Außerdem besteht die Gefahr das ein ARP Eintrag gelöscht
wird obwohl er eigentlich noch gebraucht wird !

Ich würde es einfach hier mit eintragen:

void eth_get_data (void)
{
  if(eth.timer)
  {
    tcp_timer_call();
    arp_timer_call();
    eth.timer = 0;
  }


Gruß
 holger
Gast #744818
Lesenswert?

Hallo,

da ich in der letzten Zeit kaum etwas µC-artiges gemacht habe, war ich 
doch etwas überrascht, dass nun schon Version 53(?) aktuell ist. Zuletzt 
habe ich irgendwas um die 40 verwendet.

Da ich recht viel Aufwand in meine httpd gesteckt habe, die Frage, ob 
ich die stack.c/h und enc28j60.c/h einfach so austauschen kann oder hat 
sich auch an den Schnittstellen zwischen den Modulen was geändert?

Gruß
Steffen.
Gast #745545
Lesenswert?

Funktioniert der aktuelle Code von Ulrich (7.1.2008) noch mit einem 
atmega32?

Ich hab folgendes Problem ich habe mit der fertigen hex von Ulrich einen 
erfolgreichen test gemacht das geht wunderbar. Wenn ich dann versuch 
noch mal selbst zu kompilieren (makefile MCU = atmega32) geht nix mehr.

Bin ich nur zu blöd oder hab ich was übersehen oder geht das einfach 
nicht?

Gruss Sven
Gast #746281
Lesenswert?

Hey danke für die schnelle Hilfe, das war genau mein Problem.
Ich find das Projekt echt super ok die Hardware von dir benutz ich nicht 
ich hatte da noch was eigenes rumfahren. Aber die Software ist super, 
Hut ab Ulrich.

Mit freundlichen Grüßen Sven
Gast #746484
Lesenswert?

Ich war einige Zeit offline.

"Sicher, dass das überhaupt etwas an Rechenleistung braucht? Ich bin mir
ziemlich sicher, dass der Compiler hier nur noch die Zugriffsreihenfolge
in den Speicher beachtet, wenn er Variablen in oder aus Register/n 
holt."

Dann schau Dir mal das Assemblerlisting an, es werden etliche unnötige 
'clr' und 'or' verbraten.

Ich mache solche Zugriffe immer mit Unions, da weiß der Compiler gleich, 
was ich meine:

#define lo 0
#define hi 1
union {unsigned long l;unsigned int i[2];unsigned char c[4]} test;
oder mittels typedef
und die Zugriffe dann mit test.l=0x12345678  test.i[hi] oder test.i[lo] 
oder test.c[0]



@Holger, @Sascha
Überraschung:
while((len--))
ist für WinAVR nicht gleich mit dem viel schneller ausgeführten
while((len=len-1)),
hier verwendet er das vom sbic gesetzte Z-Flag für den Branch!

Ich sehe überall noch Optimierungspotential.

Versuchsweise mal das versucht:
while((len.c[hi]--))
  while((len.c[lo]--)){
    send...
  }
Das habe ich schreiben können, wie ich wollte (auch mit do..while), er 
hat nie das Zero-Flag direkt ausgewertet. Trotzdem es so noch schneller 
ginge, hat der Compiler es immer langsamer gemacht.

Übrigens ist empfohlen (für bessere Lesbarkeit), doppelt zu klammern, 
wenn man ein non-bool-Wert als bool verwendet.
Gast #746513
Lesenswert?

Noch was:
Es lohnt sich einfach nicht, wegen 10 Bytes Code eine Sub zu callen.
Zuerst versuchte ich, Zeit zu sparen, indem ich die untersten Level mit
inline
in die nächst höheren Ebenen einzubinden.
Das macht er zwar, aber anders als ich mir das vorgestellt hatte.
Er verwendet für die Übergabe die std-Register (r24 & co), lediglich der 
Call und der Ret werden eingespart.

Wesentlich besser ist es, die unteren Level z.B. als
#define enc28j60_read_address( ....
anzugeben, dann werden sie wirklich eingebunden und die Register 
individuell und optimal verwendet.
Gast #747008
Lesenswert?

>Übrigens ist empfohlen (für bessere Lesbarkeit), doppelt zu klammern,
>wenn man ein non-bool-Wert als bool verwendet.

Was heisst "ist empfohlen"? Wer empfiehlt das?  Hast du einen Link, in 
dem solche Tipps gegeben werden? Gibt es da einen Standard? Würde mich 
mal interessieren, was sonst noch so gibt.

Gruß
Steffen.
Gast #747480
Lesenswert?

Hi Ulrich,

Ich hätte da (wieder :( mal einen Vorschlag.
Es geht um das %END was da bei den Arrays im Flash
immer abgefragt wird. Man kann das umgehen.

Beim NTP habe ich es mal rausgenommen und
über sizeof(NTP_Request) einfach die Länge mit
dem Compiler abgefragt. Funktioniert.
Siehe geänderter Code für ntp.c im Anhang.

Beim httpd dürfte es etwas schwieriger werden
da man mit dem Pointer auf das Objekt nicht
mit sizeof() die Länge abfragen kann.
Da müsste wohl noch die Längenangabe in die
struct http_table mit rein. Diese müsste man
in httpd_header_check() eintragen lassen.

Oder gleich in webpage.h machen

  typedef struct
  {
    const char *filename;    //Dateiname der Seite
    PGM_P page_pointer;      //Zeiger auf Speicherinhalt
                unsigned int size;              //Größe des Objektes
  } WEBPAGE_ITEM;

WEBPAGE_ITEM WEBPAGE_TABLE[] = // Befehls-Tabelle
{
  {"index.htm",Page1,sizeof(Page1)},
  {"Status.htm",Page4,sizeof(Page4)},

Der Vorteil wäre das Grafiken aus dem Flash
schneller geladen werden könnten weil nicht
bei jedem Byte auch gleich noch auf %END gecheckt wird.

Über http_entry[index].http_header_type könnte man dann
entscheiden: Ist das ne HTM die geparst werden muss oder
kann ich die Grafik einfach so in den Puffer kopieren ?
Ein weiteres Problem ist dann natürlich: Passt die Grafik
komplett in den Puffer, oder müssen mehrere Stückchen
gesendet werden.

Hört sich kompliziert an und ist auch nur mal was
zum nachdenken.

PS: Ändere in der Status.htm doch mal "Sart" auf "Start" ;)

Gruß
 Holger
Angehängte Dateien:
Persönliche Seite #747548
Lesenswert?

holger wrote:
> Beim httpd dürfte es etwas schwieriger werden
> da man mit dem Pointer auf das Objekt nicht
> mit sizeof() die Länge abfragen kann.
> Da müsste wohl noch die Längenangabe in die
> struct http_table mit rein. Diese müsste man
> in httpd_header_check() eintragen lassen.

Ähem, wofür gibt es in C eigentlich den String-Ende-Terminator?
Persönliche Seite #747574
Lesenswert?

holger wrote:
>>Nein, aber für eine Webseite würde das funktionieren.
>
> Da hast du recht.


Ich wusste ja nicht, dass ihr auch Bilder sendet ;) ;)

Bei meiner kleinen Webserverapplikation enthält das Socket-Struct (Also 
das Struct, was die Daten für jeden TCP-Socket von einem Webserveraufruf 
zum anderen mitführt) einen Zeiger auf die Daten und einen Zähler, der 
anzeigt, wieviele Bytes noch versendet werden müssen, bis die Seite/Bild 
fertig ist. Das hat den Vorteil, dass man bei Retransmissions leichter 
die Position im Speicher wiederfindet, die man erneut senden muss.
Gast #747606
Lesenswert?

Hallo,

Das mit der Endmakierung ist wie schon gesagt auf die Bilder 
zurückzuführen. Da diese ja keine Strings sind aber in der gleichen 
Routine verarbeitet werden. Da ich sowieso immer das % Abfrage für 
dynamische Inhalte ist dahingestellt ob ein anderes verfahren viel mehr 
bringt.

Gruß
Uli
Persönliche Seite #747620
Lesenswert?

Ulrich Radig wrote:
> Schon wieder nicht eingeloggt gewesen :-(
>
> Simon K.
>
>>Ich wusste ja nicht, dass ihr auch Bilder sendet ;) ;)
>
> Sogar Livebilder einer Kamera ;-)
>
> Gruß
> Uli

Stimmt, da war was.

Sag mal, du sagtest, dass du das "%" für dynamische Inhalte benutzt. Das 
heißt beim Kopieren in den Ethernet-Buffer ersetzt du die %-Variablen 
on-the-fly durch den dynamischen Inhalt, richtig? Wie hast du das 
Problem umgangen, dass nach dem "expandieren" also ersetzen der 
%-Variable ein so langer String herauskommt, dass er nicht mehr in das 
aktuelle Paket passt, sondern im nächsten versand werden muss (bzw. 
aufgeteilt werden muss).

Hast du da einen Check eingebaut? Oder versendest du dynamischen Inhalt 
jeweils in einem eigenen Ethernet-Paket? Oder wie machst du dit.
Gast #749330
Lesenswert?

Hi Ulrich,

hab das mit der Abfrage von %END jetzt viel einfacher gelöst:

//Müssen Variablen ins Packet eingesetzt werden? ===> %VA@00 bis %VA@09
if (b == '%')
{
  //wurde das Ende des Packetes erreicht?
  //Verbindung TCP Port kann beim nächsten ACK geschlossen werden
  //Schleife wird abgebrochen keine Daten mehr!!
  if (strncasecmp_P("END",http_entry[index].new_page_pointer,3)==0)
      {
        tcp_entry[index].app_status = 0xFFFD;
        //a++;
        break;
      }

  if (strncasecmp_P("VA@",http_entry[index].new_page_pointer,3)==0)

So wird bei den Grafiken nicht bei JEDEM Byte komplett auf %END 
gecheckt.

Gruß
 holger
Gast #749568
Lesenswert?

Diese Methode mit der Untersuchung auf "%" ist besonders sinnvoll, wenn 
man mehrere Abfragen hat (%END, %VA@xx, %VI@xx, ...). Vielleicht ist es 
auch sinnvoll, unterschiedliche Methoden für Daten mit und ohne "%" zu 
implementieren. So spart man sich die Abfragen und die Pakete können 
komplett ausgenutzt werden.

Steffen.
OP Persönliche Seite #749591
Lesenswert?

@Steffen,

Ich hatte auch schon mal daran gedacht dieses aber verworfen da ich 
Probleme mit Retransmission hatte. Hier wusste ich nie ob das letzte 
Packet 1 oder 2Packete waren. Da sich ja der Inhalt der Variablen und 
somit die Anzahl der Packete ändern kann. Das meine Methode nicht die 
beste ist ist mir klar, aber ich habe immer die gleiche Packetanzahl 
bezüglich Retransmission.

Gruß
Uli
Gast #752098
Lesenswert?

Hallo,

da ich momentan Hardwareprobleme habe und noch auf Teile warte, habe ich 
mich mal um was anderes gekümmert.

Wie entwickelt ihr euren HTML, CSS, JavaScript,... Code?
1. In einem normalen (Web) Editor die Dateien fertig machen (Die Dateien 
können sofort im Browser angeschaut werden)
2. Ersetzen von " durch  \"
3. Jede Zeile in "..." einfassen
4. "%END" ans Ende einfügen
5. kopieren des ganzen Codes und einfügen in eine PROGMEM-Variable in 
der webpage.h

????

So mache ich es momentan. Um den Vorgang ein wenig zu beschleunigen 
wollte ich mir ein Tool schreiben, welches (per Kommandozeile --> in 
makefile einzubinden?) aus einer ausgewählten Datei das Zielformat 
erstellt. Die Datei kann dann z.B. durch
1
#include "webseiten\home.html.h"
in die webpage.h eingebunden werden.

Fällt euch etwas ein, was dagegen spricht? Muss ich noch irgendwelche 
Sonderfälle beachten, die mir gerade nicht einfallen? Für Hinweise wäre 
ich dankbar. Falls ich es dann hinbekomme, könnt ihr das Programm auch 
gerne nutzen.

Hat jemand von euch ähnliche Tools geschrieben, die die Entwicklung 
mit/für den Webserver vereinfachen?

Gruß
Steffen.
Gast #752933
Lesenswert?

Hallo Steffen,

ich verwende dazu unter Linux (unter Windows geht auch cygwin) ein 
kleines
Script das die ganze Arbeit erledigt:

$ sed 's/"/\\"/g' < page1.html | awk 'BEGIN { print "PROGMEM char 
Page1[] = {" } { print "\"" $0 "\\r\\n\"" } END { print "\"%END\"\n};"}' 
> page1.html.h

Mein HTML Code steht dabei in der Datei page1.html und wird in die
Header-Datei page1.html.h geschrieben.

Der sed Teil erledigt das Ersetzen von " durch \" und der awk Teil 
erledigt
den ganzen Rest.


Gruß
Gerd.
Gast #753832
Lesenswert?

Hallo

ich habe mir den 1.0.56 stack heruntergeladen und wollte das alles mit 
winavr kompillieren.
leider kommt folgender fehler:

networkcard/enc28j60.c:117: error: `SPIE' undeclared (first use in this 
function)
networkcard/enc28j60.c:117: error: (Each undeclared identifier is 
reported only once
networkcard/enc28j60.c:117: error: for each function it appears in.)
networkcard/enc28j60.c:117: error: `CPHA' undeclared (first use in this 
function)

ich weiß auch nicht so recht wo ich das alles deklarieren soll. kann mir 
da jemand weiterhelfen?
OP Persönliche Seite #754414
Lesenswert?

Hallo,

Ich habe einen komplett neuen Webserver auf SMD Basis! Mit einigen neuen 
Funktionen. Aber die alte Software ist und bleibt kompatibel. Die 
Platine kommt am 23.1. bei mir an und wird getestet. Danach wird das 
Projekt wieder wie gewohnt auf meiner Webseite veröffentlicht. Da nur 
SMD Bauteile zum Einsatz kommen ist dieser Webserver nicht unbedingt für 
Anfänger geeignet.

Gruß
Uli
Gast #754535
Lesenswert?

Ich habe die Platine komplett bestückt und wollte die testen, aber 
leider passiert nichts. Am AVR sind 0V.
Beim ersten Start Leuchtete die LED1 kurz auf. Jetzt aber nicht mehr.

Wie gehe ich am besten vor? Wo muss ich Messen um das Problem 
einzugrenzen?
Am Eingang liegen 12V an.


Vielen Dank für Eure hilfe.
Gast #754615
Lesenswert?

Aso ^^ ... nicht gut. Wo stand es von 9V? habs Überlesen. Ich dachte ein 
7805 wird benutzt und man kann mehr als 12V benutzen ;-).

Kann ich die Sicherung überbrücken?`Hab nämlich keine mehr ... und will 
nicht auf Reichelt warten.

Habe ein Stabilisiertes 9V Netzteil.

Ist die Sicherung auf 9V begrenzt?
Gast #754620
Lesenswert?

>Ist die Sicherung auf 9V begrenzt?
Sicherungen begrenzten den Strom... im Allgemeinen ist dieser Wert 
Spannungsunabhängig (naja, eine gewisse Leistung muß schon an der 
Sicherung abfallen, damit sie durchbrennt...).

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren