32 x 32 rgb ledmatrix

Beste allemaal,

Ik ben bezig met een klein projectje maar het lukt mij niet om het goed te krijgen.
Ik stuur met een Arduino uno een RGB led paneel aan met 32 x 32 leds.
Ik krijg wel beeld op het scherm maar het staat helaas allemaal door elkaar weten jullie misschien wat het probleem is?

code:


#define CLK 11  // MUST be on PORTB! (Use pin 11 on Mega)
#define OE  9
#define LAT 10
#define A   A0
#define B   A1
#define C   A2
#define D   A3
// If your matrix has the DOUBLE HEADER input, use:
//#define CLK 8  // MUST be on PORTB! (Use pin 11 on Mega)
//#define LAT 9
//#define OE  10
//#define A   A3
//#define B   A2
//#define C   A1
//#define D   A0
RGBmatrixPanel matrix(A, B, C, D, CLK, LAT, OE, false);

void setup() {

  matrix.begin();

Alvast bedankt voor jullie reacties.

Met vriendelijke groet, Raymond.

Als het zo ver werkt zul je een aansluitfoutje maken. Check en dubbelchek, of beredeneer hoe het zou moeten :)
Overigens is de informatie wat summier, er zullen gezien de signalen 595's aan die matrix hangen oid ?

pax

Golden Member

Hallo Raymond,

mocht je idd. 595s gebruiken, ik heb hier ook wel eens problemen mee gehad. Een pull-down weerstandje van 100k tussen RCK (pen 12 en massa) verhielp het probleem.
Hopelijk heb je hier wat aan.

Met vriendelijke groet,
cor

Arco

Special Member

Zo te zien is die matrix opgebouwd uit 8x8 displays. De 2e en 3e horizontale rij displays (9...16 en 17...24) zijn zo te zien omgewisseld.

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Dank jullie,

Cor ik gebruik alleen pin 12 niet en zou je me uit kunnen leggen wat de term RCK betekent?
Dit is trouwens een bestaand paneel waar die grote panelen mee worden opgebouwd.
Aart wat is een 595s?

Bij voorbaat dank allemaal!

benleentje

Golden Member

Zet anders eens een groot kruis op het scherm dan kan je eventueel zien wat er fout is. NU weet ik niet eens wat plaatje zou moeten zijn.

Mensen zijn soms net als een gelijkrichter, ze willen graag hun gelijk hebben.

..of een lopend ledje die regel voor regel afloopt

[Bericht gewijzigd door ohm pi op vrijdag 14 oktober 2016 22:01:31 (42%)

Arco

Special Member

Aan de cirkels te zien, ontbreken er precies 8 ledregels (9...16), die staan daaronder...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Een 74HC595 is een shift register.
Wordt gebruikt om meerdere uitgangen te creëren met een paar poorten van de arduino.
https://www.arduino.cc/en/Tutorial/ShiftOut

Is het ook de bedoeling dat er twee cirkels getekend wordt?

Arco

Special Member

Is inderdaad een wat ongelukkige afbeelding om een display te testen... ;)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
rudig76

Golden Member

Lijkt erop dat dit bord gebruikt word

https://www.adafruit.com/products/420

Met deze code van adafruit:

https://github.com/adafruit/RGB-matrix-Panel

Deze code ondersteund 16x32 displays en vooralsnog niet het "doorlussen" zoals het display zelf wel ondersteund.
Daarom lijkt het mis te gaan.

Je zou kunnen kijken of je de code zo kunt aanpassen dat 32x32 wel werkt, maar zal vast niet heel simpel zijn.

Iets heel anders :-) http://www.echteworst.nl

Bedankt voor alle info tot zover.
Ik zit nu voor mijn vakantie in Oostenrijk dus zal er niet eerder als volgende week mee verder kunnen.
Top allemaal!

Op 15 oktober 2016 09:10:19 schreef rudig76:
Lijkt erop dat dit bord gebruikt word

https://www.adafruit.com/products/420

Met deze code van adafruit:

https://github.com/adafruit/RGB-matrix-Panel

Deze code ondersteund 16x32 displays en vooralsnog niet het "doorlussen" zoals het display zelf wel ondersteund.
Daarom lijkt het mis te gaan.

Je zou kunnen kijken of je de code zo kunt aanpassen dat 32x32 wel werkt, maar zal vast niet heel simpel zijn.

Dat klopt ik heb die codes ook gebruikt van Adafruit en het lijkt erop dat er precies 2x het zelfde wordt geprojecteerd op het scherm.

rudig76

Golden Member

Nog even zitten zoeken in die code. Maar er is ook een fuctie voor de 32x32 matrix. Echter dan dien je bij de initialisatie rows en height mee te geven.

Kun je dat is proberen:

void RGBmatrixPanel::init(uint8_t rows, uint8_t a, uint8_t b, uint8_t c,
uint8_t sclk, uint8_t latch, uint8_t oe, boolean dbuf, uint8_t width)

Waar nu staat:

RGBmatrixPanel matrix(A, B, C, D, CLK, LAT, OE, false);

Moet worden:

RGBmatrixPanel matrix(32,A, B, C, D, CLK, LAT, OE, false, 32);

[Bericht gewijzigd door rudig76 op dinsdag 25 oktober 2016 20:01:50 (20%)

Iets heel anders :-) http://www.echteworst.nl

Ik heb toch het paneel moeten pakken van ada fruit want zon chinees ding slikt het niet.
Nu doet hij het whit the first try!
Bedankt allemaal!

Nu alleen even uitvogellen hoe ik de pixels individueel kan aansturen.
Als iemand sugesties heeft zijn die altijd welkom?

Allemaal hartelijk bedankt!

rudig76

Golden Member

Kijk ff naar dit voorbeeld:

https://github.com/adafruit/RGB-matrix-Panel/blob/master/examples/test…

Daar staat oa deze functie in die ze gebruiken,

c code:


  // draw a pixel in solid white
  matrix.drawPixel(0, 0, matrix.Color333(7, 7, 7)); 

Ga er mee spelen en je komt een heel eind

Iets heel anders :-) http://www.echteworst.nl

Ja zat ik ook al aan te denken.
Het enige nadeel is wel dat je veel pixels moet benoemen om een plaatje te creëren.
Volgens mij kun je ook iedere pixel een adres geven en in dat adres is dan ook de kleur verwerkt en dat adres bestaat dan maar uit 4 of 5 karakters dus wordt het programma aanzienlijk kleiner.
Ik ga nog effe lekker verder stoeien.

Bedankt voor de input Rudig76.

Dan moet je een functie maken welke je in je void loop() oproept.

Krijg je iets in de richting van
Void pixel(x, y, color){
.....
}

Hoe je precies de functie schrijft weet ik niet precies. Heb in het verleden met PHP wel eens functies geschreven welke op die manier werkten. Blijft de code ook overzichtelijker en natuurlijk hoef je niet elke keer hetzelfde te herhalen.
Om de functie dan aan te roepen krijg je bijvoorbeeld pixel(10, 10, blue); om de tiende rij horizontaal te selecteren en de tiende rij vertikaal met blauw.

Edit:
Zie nu dat Rudig76 al een bestaande functie aangaf.

Hoewel ik er zelf (buiten gebruik voor 32x64 OLED display'tjes) geen ervaring mee heb zou ik al snel kijken naar de gfx library.

Ik heb een andere 32x32 matrix moeten gebruiken.
Deze communiceert met een HUB75H protocol.
De ander met een HUB75 en daar gaat het wel mee.
Nu heb ik een stukje code geschreven en dat werkt.
Nu is mijn vraag hoe kan ik de code dusdanig aanpassen dat ik iedere keer als ik onder aan ben bij void loop meteen weer bovenaan begin bij void setup?

code:

// testshapes demo for Adafruit RGBmatrixPanel library.
// Demonstrates the drawing abilities of the RGBmatrixPanel library.
// For 32x32 RGB LED matrix:
// http://www.adafruit.com/products/607

// Written by Limor Fried/Ladyada & Phil Burgess/PaintYourDragon
// for Adafruit Industries.
// BSD license, all text above must be included in any redistribution.

#include <Adafruit_GFX.h>   // Core graphics library
#include <RGBmatrixPanel.h> // Hardware-specific library

// If your 32x32 matrix has the SINGLE HEADER input,
// use this pinout:
#define CLK 8  // MUST be on PORTB! (Use pin 11 on Mega)
#define OE  9
#define LAT 10
#define A   A0
#define B   A1
#define C   A2
#define D   A3
// If your matrix has the DOUBLE HEADER input, use:
//#define CLK 8  // MUST be on PORTB! (Use pin 11 on Mega)
//#define LAT 9
//#define OE  10
//#define A   A3
//#define B   A2
//#define C   A1
//#define D   A0
RGBmatrixPanel matrix(A, B, C, D, CLK, LAT, OE, false);


 void setup() {

  matrix.begin();

  matrix.setCursor(-7, 9);    // start at top left, with one pixel of spacing
  matrix.setTextSize(2);     // size 1 == 8 pixels high
  matrix.setTextWrap(false); // Don't wrap at end of line - will do ourselves

  matrix.setTextColor(matrix.Color333(7,7,7));
  matrix.println(" 7O ");
  delay(1000);

  matrix.fillScreen(matrix.Color333(0, 0, 0));

  matrix.setCursor(-7, 9);    // start at top left, with one pixel of spacing
  matrix.setTextSize(2);     // size 1 == 8 pixels high
  matrix.setTextWrap(false); // Don't wrap at end of line - will do ourselves

  matrix.setTextColor(matrix.Color333(7,7,7));
  matrix.println(" 9O ");
  delay(1000);

  matrix.fillScreen(matrix.Color333(0, 0, 0));

  matrix.setCursor(-14, 9);    // start at top left, with one pixel of spacing
  matrix.setTextSize(2);     // size 1 == 8 pixels high
  matrix.setTextWrap(false); // Don't wrap at end of line - will do ourselves

  matrix.setTextColor(matrix.Color333(7,7,7));
  matrix.println(" 12O ");
  delay(1000);

  matrix.fillScreen(matrix.Color333(0, 0, 0));

  matrix.setCursor(-14, 9);    // start at top left, with one pixel of spacing
  matrix.setTextSize(2);     // size 1 == 8 pixels high
  matrix.setTextWrap(false); // Don't wrap at end of line - will do ourselves

  matrix.setTextColor(matrix.Color333(7,7,7));
  matrix.println(" 13O ");
  delay(1000);

  matrix.fillScreen(matrix.Color333(0, 0, 0));

   // draw a box in red
  matrix.drawRect(0, 0, 32, 32, matrix.Color333(10,0,0));
  matrix.drawRect(1, 1, 30, 30, matrix.Color333(10,0,0));
  matrix.drawRect(2, 2, 28, 28, matrix.Color333(10,0,0));


  // draw line 8
  matrix.drawPixel(6, 8, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(7, 8, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(8, 8, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(9, 8, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(10, 8, matrix.Color333(7, 7, 7)); 

    // draw line 9
  matrix.drawPixel(6, 9, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(10, 9, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(11, 9, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(12, 9, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(13, 9, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(14, 9, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(15, 9, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(16, 9, matrix.Color333(7, 7, 7)); 

     // draw line 10
  matrix.drawPixel(5, 10, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(6, 10, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(7, 10, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(8, 10, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(9, 10, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(10, 10, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(16, 10, matrix.Color333(7, 7, 7)); 

      // draw line 11
  matrix.drawPixel(5, 11, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(9, 11, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(17, 11, matrix.Color333(7, 7, 7)); 

   // draw line 12
  matrix.drawPixel(5, 12, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(6, 12, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(7, 12, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(8, 12, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(9, 12, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(15, 12, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(16, 12, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(17, 12, matrix.Color333(7, 7, 7));
  matrix.drawPixel(18, 12, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(19, 12, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(20, 12, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(21, 12, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(22, 12, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(23, 12, matrix.Color333(7, 7, 7)); 

   // draw line 13
  matrix.drawPixel(6, 13, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(8, 13, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(9, 13, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(10, 13, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(11, 13, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(12, 13, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(13, 13, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(14, 13, matrix.Color333(7, 7, 7));
  matrix.drawPixel(15, 13, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(23, 13, matrix.Color333(7, 7, 7)); 

   // draw line 14
  matrix.drawPixel(8, 14, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(15, 14, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(23, 14, matrix.Color333(7, 7, 7)); 

   // draw line 15
  matrix.drawPixel(8, 15, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(14, 15, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(24, 15, matrix.Color333(7, 7, 7)); 

  // draw line 16
  matrix.drawPixel(8, 16, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(9, 16, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(10, 16, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(11, 16, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(12, 16, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(13, 16, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(14, 16, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(24, 16, matrix.Color333(7, 7, 7)); 

   // draw line 17
  matrix.drawPixel(9, 17, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(10, 17, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(13, 17, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(14, 17, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(15, 17, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(16, 17, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(17, 17, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(18, 17, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(19, 17, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(20, 17, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(21, 17, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(22, 17, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(23, 17, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(24, 17, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(25, 17, matrix.Color333(7, 7, 7)); 

   // draw line 18
  matrix.drawPixel(9, 18, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(10, 18, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(13, 18, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(25, 18, matrix.Color333(7, 7, 7)); 

   // draw line 19
  matrix.drawPixel(13, 19, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(15, 19, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(16, 19, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(17, 19, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(21, 19, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(22, 19, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(23, 19, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(25, 19, matrix.Color333(7, 7, 7)); 

   // draw line 20
  matrix.drawPixel(13, 20, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(25, 20, matrix.Color333(7, 7, 7));

   // draw line 21
  matrix.drawPixel(13, 21, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(14, 21, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(15, 21, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(16, 21, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(17, 21, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(18, 21, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(19, 21, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(20, 21, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(21, 21, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(22, 21, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(23, 21, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(24, 21, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(25, 21, matrix.Color333(7, 7, 7)); 

   // draw line 22
  matrix.drawPixel(14, 22, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(15, 22, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(16, 22, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(22, 22, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(23, 22, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(24, 22, matrix.Color333(7, 7, 7)); 

   // draw line 23
  matrix.drawPixel(14, 23, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(15, 23, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(16, 23, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(22, 23, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(23, 23, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(24, 23, matrix.Color333(7, 7, 7)); 

   // draw line 24
  matrix.drawPixel(14, 24, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(15, 24, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(16, 24, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(22, 24, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(23, 24, matrix.Color333(7, 7, 7)); 
  matrix.drawPixel(24, 24, matrix.Color333(7, 7, 7)); 

   
  // whew!
  }

  
void loop() {
 

  
}


eSe

Honourable Member

Ik ken het protocol HUB75H niet, heb wel een idee wat er gebeurt.
Je kan NIET terugspringen naar 'void setup()', dit is wat het zegt, een 1-malig gebeuren, initialisatie van allerlei poorten, variabelen, constanten...
Programma's (sketch, jakkes, in Arduino parlando) draaien in 'void loop()', dat is wat het zegt, draai hier rond in een circel, bij het eind van loop ga terug naar het begin. In puur c/c++ zou dit 'main' heten.
Ik denk dat je ook best gebruik maakt van functies in plaats van alles gewoon onder elkaar te zetten en tientallen keren hetzelfde te schrijven. Een array met de puntjes (x,y) en hun kleur. Dan met een teller je array aflopen. Maar daarvoor zal je even wat voorbeelden moeten bestuderen. Zie Arduino site voor een zillioen voorbeelden.

Groetjes,
eSe

CChheecckk yyoouurr dduupplleexx sswwiittcchh..
Arco

Special Member

Wow, dit bedoelde ik laatst in een ander topic met vreselijk geschreven code... :)
De hele drawpixel lap met code kun je door een paar regels vervangen. (pseudocode)

pic basic code:


Const XYPos As byte[242] =   
  (6, 8, 7, 8, 8, 8, 9, 8,10, 8, 6, 9,10, 9,11, 9,12, 9,13, 9,14, 9,15, 9,
  16, 9, 5,10, 6,10, 7,10, 8,10, 9,10,10,10,16,10, 5,11, 9,11,17,11, 5,12, 
   6,12, 7,12, 8,12, 9,12,15,12,16,12,17,12,18,12,19,12,20,12,21,12,22,12,  
  23,12, 6,13, 8,13, 9,13,10,13,11,13,12,13,13,13,14,13,15,13,23,13, 8,14, 
  15,14,23,14, 8,15,14,15,24,15, 8,16, 9,16,10,16,11,16,12,16,13,16,14,16, 
  24,16, 9,17,10,17,13,17,14,17,15,17,16,17,17,17,18,17,19,17,20,17,21,17, 
  22,17,23,17,24,17,25,17, 9,18,10,18,13,18,25,18,13,19,15,19,16,19,17,19,                   
  21,19,22,19,23,19,25,19,13,20,25,20,13,21,14,21,15,21,16,21,17,21,18,21,
  19,21,20,21,21,21,22,21,23,21,24,21,25,21,14,22,15,22,16,22,22,22,23,22, 
  24,22,14,23,15,23,16,23,22,23,23,23,24,23,14,24,15,24,16,24,22,24,23,24,
  24,24) 

  For cnt = 0 to Ubound(XYPos)-1 step 2
    matrix.drawPixel(XYPos[cnt], XYPos[cnt+1], matrix.Color333(7, 7, 7))
  Next cnt
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
buckfast_beekeeper

Golden Member

Jesus, wat een code.

iets wat moet herhaalt worden steek je normaler wijze in een (main) loop. De setup wordt 1 keer afgehandeld. Tenzij je het altijd weer gaat aanroepen in een main. Dan is wel de naam setup verkeert gekozen.

Van Lambiek wordt goede geuze gemaakt.