Gå til innhold

Den lille Arduino-tråden


Anbefalte innlegg

Videoannonse
Annonse

Heisann!

 

Jeg driver å lager en rfid-lås der jeg monterer en 28byj-48 steppermotor rett på dørvrideren. Jeg har klart å få koden til rfid riktig, men hvordan implementerer jeg stepper koden inn i godkjenninga? Koden må vite om dørvrideren enten er låst eller åpen.

 

Legger ved koden:

 


#include

#define uchar unsigned char
#define uint unsigned int
#define MAX_LEN 16
#include
#define HALFSTEP 8

const int p10 = 10;
const int p5 = 5;
const int p11 = 5;
const int p12 = 5;
const int p13 = 5;

char* GREEN[]={"136", "4", "189","251","202","64","1364189251202"};
char* YELLOW[]={"7", "1", "9","4","13","62","136410167170"};
boolean red=true;

#define PCD_IDLE 0 //NO action; Cancel the current command
#define PCD_AUTHENT 14 //Authentication Key
#define PCD_TRANSCEIVE 12 //Transmit and receive data,
#define PCD_RESETPHASE 15 //Reset
#define PCD_CALCCRC 3 //CRC Calculate
# define PICC_REQIDL 38 // find the antenna area does not enter hibernation
# define PICC_ANTICOLL 147 // anti-collision
# define PICC_SElECTTAG 147 // election card
# define PICC_READ 48 // Read Block
# define PICC_WRITE 160 // write block
# define PICC_HALT 80 // Sleep
#define MI_OK 0
#define MI_NOTAGERR 1
#define MI_ERR 2
#define CommandReg 1
#define CommIEnReg 2
#define CommIrqReg 4
#define DivIrqReg 5
#define ErrorReg 6
#define Status2Reg 8
#define FIFODataReg 9
#define FIFOLevelReg 10
#define ControlReg 12
#define BitFramingReg 13
#define CollReg 14
#define ModeReg 17
#define TxControlReg 20
#define TxAutoReg 21
#define CRCResultRegM 33
#define CRCResultRegL 34
#define TModeReg 42
#define TPrescalerReg 43
#define TReloadRegH 44
#define TReloadRegL 45
#define motorPin1 3 // IN1 on the ULN2003 driver 1
#define motorPin2 4 // IN2 on the ULN2003 driver 1
#define motorPin3 6 // IN3 on the ULN2003 driver 1
#define motorPin4 7 // IN4 on the ULN2003 driver 1
// Initialize with pin sequence IN1-IN3-IN2-IN4 for using the AccelStepper with 28BYJ-48
AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);

//4 bytes card serial number, the first 5 bytes for the checksum byte
uchar serNum[5];

void setup() {
Serial.begin(9600); // RFID reader SOUT pin connected to Serial RX pin at 2400bps
// start the SPI library:
SPI.begin();
pinMode(p10,OUTPUT); // Set digital pin 10 as OUTPUT to connect it to the RFID /ENABLE pin
digitalWrite(p10, LOW); // Activate the RFID reader
pinMode(p5,OUTPUT); // Set digital pin 10 , Not Reset and Power-down
digitalWrite(p5, HIGH);
pinMode(A2,OUTPUT);
pinMode(A1,OUTPUT);
pinMode(A0,OUTPUT);
pinMode(8,OUTPUT);
rfid_Init();
stepper1.setMaxSpeed(1000.0);
stepper1.setAcceleration(1000.0);
stepper1.setSpeed(2000);
stepper1.moveTo(2000);

}

void loop(){
uchar i,tmp, checksum1;
uchar status;
uchar str[MAX_LEN];
uchar RC_size;
uchar blockAddr; //Selection operation block address 0 to 63
String mynum = "";

//Find cards, return card type
status = rfid_Request(PICC_REQIDL, str);

//Anti-collision, return card serial number 4 bytes
status = rfid_Anticoll(str);
memcpy(serNum, str, 5);
if (status == MI_OK)
{
Serial.print("Card id: ");
Serial.print(serNum[0]);
Serial.print(" , ");
Serial.print(serNum[1]);
Serial.print(" , ");
Serial.print(serNum[2]);
Serial.print(" , ");
Serial.print(serNum[3]);
Serial.print(" , ");
Serial.print(serNum[4]);
Serial.println(" ");

String item="";
for(int k=0; k<5; k++){
item += String(serNum[k]);
}

Serial.println(item);

int GY=sizeof(GREEN)+sizeof(YELLOW);
red=true;

for(i=0;i
if(item==GREEN){
red=false;
Serial.println("Green");
digitalWrite(A2,HIGH);
tone(8, 428);
delay(360);
noTone(8);
digitalWrite(A2,LOW);
break;
}else if(item==YELLOW){
red=false;
Serial.println("Yellow");
digitalWrite(A0,HIGH);
tone(8, 444);
delay(150);
noTone(8);
delay(60);
tone(8, 446);
delay(150);
noTone(8);
digitalWrite(A0,LOW);
break;
}else{

}

}//end for

if(red==true){
Serial.println("Red");
digitalWrite(A1,HIGH);
tone(8, 664);
delay(140);
noTone(8);
delay(60);
tone(8, 664);
delay(140);
noTone(8);
delay(60);
tone(8, 664);
delay(140);
noTone(8);
digitalWrite(A1,LOW);
}

delay(1000);
}//end mi_ok if
rfid_Halt();
}//end loop

//To a certain rfid register to write a byte of data

void Write_rfid(uchar addr, uchar val)
{
digitalWrite(p10, LOW);
SPI.transfer((addr<<1)&126);
SPI.transfer(val);

digitalWrite(p10, HIGH);
}


//From a certain rfid read a byte of data register

uchar Read_rfid(uchar addr)
{
uchar val;

digitalWrite(p10, LOW);

//Address Format:1XXXXXX0
SPI.transfer(((addr<<1)&126) | 128 );
val =SPI.transfer(0);

digitalWrite(p10, HIGH);

return val;
}

//Description: Set RC522 register bit

void SetBitMask(uchar reg, uchar mask)
{
uchar tmp;
tmp = Read_rfid(reg);
Write_rfid(reg, tmp | mask); // set bit mask
}


//Description: clear RC522 register bit

void ClearBitMask(uchar reg, uchar mask)
{
uchar tmp;
tmp = Read_rfid(reg);
Write_rfid(reg, tmp & (~mask)); // clear bit mask
}

//Close antennas, each time you start or shut down the natural barrier between the transmitter should be at least 1ms interval

void AntennaOff(void)
{
ClearBitMask(TxControlReg, 3);
}



//Description: Initialize RC522

void rfid_Init(void)
{
digitalWrite(p5,HIGH);

Write_rfid(CommandReg, PCD_RESETPHASE); //RESET

//Timer: TPrescaler*TreloadVal/6.78MHz = 24ms
Write_rfid(TModeReg, 141); //Tauto=1; f(Timer) = 6.78MHz/TPreScaler
Write_rfid(TPrescalerReg, 62); //TModeReg[3..0] + TPrescalerReg
Write_rfid(TReloadRegL, 30);
Write_rfid(TReloadRegH, 0);

Write_rfid(TxAutoReg, 100); //100%ASK
Write_rfid(ModeReg, 61); //CRC Initial value 0x6363 ???


//OPEN ANTENNA
uchar temp;

temp = Read_rfid(TxControlReg);
if (!(temp & 3))
{
SetBitMask(TxControlReg, 3);
}
//OPEN the antenna

}


//Find cards, read the card type number

uchar rfid_Request(uchar reqMode, uchar *TagType)
{
uchar status;
uint backBits; //The received data bits

Write_rfid(13, 7);

TagType[0] = reqMode;
status = rfid_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);

if ((status != MI_OK) || (backBits != 16))
{
status = MI_ERR;
}

return status;
}


//RC522 and ISO14443 card communication

uchar rfid_ToCard(uchar command, uchar *sendData, uchar sendLen, uchar *backData, uint *backLen)
{
uchar status = MI_ERR;
uchar irqEn = 0;
uchar waitIRq = 0;
uchar lastBits;
uchar n;
uint i;

switch (command)
{
case PCD_AUTHENT: //Certification cards close
{
irqEn = 18;
waitIRq = 16;
break;
}
case PCD_TRANSCEIVE: //Transmit FIFO data
{
irqEn = 119;
waitIRq = 48;
break;
}
default:
break;
}

Write_rfid(CommIEnReg, irqEn|128); //Interrupt request
ClearBitMask(CommIrqReg, 128); //Clear all interrupt request bit
SetBitMask(FIFOLevelReg, 128); //FlushBuffer=1, FIFO Initialization

Write_rfid(CommandReg, PCD_IDLE); //NO action; Cancel the current command???

//Writing data to the FIFO
for (i=0; i {
Write_rfid(FIFODataReg, sendData);
}

//Execute the command
Write_rfid(CommandReg, command);
if (command == PCD_TRANSCEIVE)
{
SetBitMask(BitFramingReg, 128); //StartSend=1,transmission of data starts
}

//Waiting to receive data to complete
i = 2000; //i according to the clock frequency adjustment, the operator M1 card maximum waiting time 25ms???
do
{
n = Read_rfid(CommIrqReg);
i--;
}
while ((i!=0) && !(n&1) && !(n&waitIRq));

ClearBitMask(BitFramingReg, 128); //StartSend=0

if (i != 0)
{
if(!(Read_rfid(ErrorReg) & 27)) //BufferOvfl Collerr CRCErr ProtecolErr
{
status = MI_OK;
if (n & irqEn & 1)
{
status = MI_NOTAGERR; //??
}

if (command == PCD_TRANSCEIVE)
{
n = Read_rfid(FIFOLevelReg);
lastBits = Read_rfid(ControlReg) & 7;
if (lastBits)
{
*backLen = (n-1)*8 + lastBits;
}
else
{
*backLen = n*8;
}

if (n == 0)
{
n = 1;
}
if (n > MAX_LEN)
{
n = MAX_LEN;
}

//Reading the received data in FIFO
for (i=0; i {
backData = Read_rfid(FIFODataReg);
}
}
}
else
{
status = MI_ERR;
}

}

//SetBitMask(ControlReg,0x80); //timer stops
//Write_rfid(CommandReg, PCD_IDLE);

return status;
}


//Anti-collision detection, reading selected card serial number card
uchar rfid_Anticoll(uchar *serNum)
{
uchar status;
uchar i;
uchar serNumCheck=0;
uint unLen;

Write_rfid(13, 0);

serNum[0] = PICC_ANTICOLL;
serNum[1] = 32;
status = rfid_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);

if (status == MI_OK)
{
//Check card serial number
for (i=0; i<4; i++)
{
serNumCheck ^= serNum;
}
if (serNumCheck != serNum)
{
status = MI_ERR;
}
}

return status;
}


//CRC calculation with MF522

void CalulateCRC(uchar *pIndata, uchar len, uchar *pOutData)
{
uchar i, n;

ClearBitMask(DivIrqReg, 4);
SetBitMask(FIFOLevelReg, 128); //Clear the FIFO pointer
//Write_rfid(CommandReg, PCD_IDLE);

//Writing data to the FIFO
for (i=0; i {
Write_rfid(FIFODataReg, *(pIndata+i));
}
Write_rfid(CommandReg, PCD_CALCCRC);

//Wait CRC calculation is complete
i = 255;
do
{
n = Read_rfid(DivIrqReg);
i--;
}
while ((i!=0) && !(n&4));

//Read CRC calculation result
pOutData[0] = Read_rfid(CRCResultRegL);
pOutData[1] = Read_rfid(CRCResultRegM);
}


//election card, read the card memory capacity
uchar rfid_SelectTag(uchar *serNum)
{
uchar i;
uchar status;
uchar size;
uint recvBits;
uchar buffer[9];

buffer[0] = PICC_SElECTTAG;
buffer[1] = 112;
for (i=0; i<5; i++)
{
buffer[i+2] = *(serNum+i);
}
CalulateCRC(buffer, 7, &buffer[7]); //??
status = rfid_ToCard(PCD_TRANSCEIVE, buffer, 9, buffer, &recvBits);

if ((status == MI_OK) && (recvBits == 24))
{
size = buffer[0];
}
else
{
size = 0;
}

return size;
}


//Verify card password

uchar rfid_Auth(uchar authMode, uchar BlockAddr, uchar *Sectorkey, uchar *serNum)
{
uchar status;
uint recvBits;
uchar i;
uchar buff[12];

//Verify the command block address + sector + password + card serial number
buff[0] = authMode;
buff[1] = BlockAddr;
for (i=0; i<6; i++)
{
buff[i+2] = *(Sectorkey+i);
}
for (i=0; i<4; i++)
{
buff[i+8] = *(serNum+i);
}
status = rfid_ToCard(PCD_AUTHENT, buff, 12, buff, &recvBits);

if ((status != MI_OK) || (!(Read_rfid(Status2Reg) & 8)))
{
status = MI_ERR;
}

return status;
}


// Read block data

uchar rfid_Read(uchar blockAddr, uchar *recvData)
{
uchar status;
uint unLen;

recvData[0] = PICC_READ;
recvData[1] = blockAddr;
CalulateCRC(recvData,2, &recvData[2]);
status = rfid_ToCard(PCD_TRANSCEIVE, recvData, 4, recvData, &unLen);

if ((status != MI_OK) || (unLen != 144))
{
status = MI_ERR;
}

return status;
}


//Write block data

uchar rfid_Write(uchar blockAddr, uchar *writeData)
{
uchar status;
uint recvBits;
uchar i;
uchar buff[18];

buff[0] = PICC_WRITE;
buff[1] = blockAddr;
CalulateCRC(buff, 2, &buff[2]);
status = rfid_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &recvBits);

if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 15) != 10))
{
status = MI_ERR;
}

if (status == MI_OK)
{
for (i=0; i<16; i++) //Data to the FIFO write 16Byte
{
buff = *(writeData+i);
}
CalulateCRC(buff, 16, &buff[16]);
status = rfid_ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits);

if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 15) != 10))
{
status = MI_ERR;
}
}

return status;
}


//Command card into hibernation

void rfid_Halt(void)
{
uchar status;
uint unLen;
uchar buff[4];

buff[0] = PICC_HALT;
buff[1] = 0;
CalulateCRC(buff, 2, &buff[2]);

status = rfid_ToCard(PCD_TRANSCEIVE, buff, 4, buff,&unLen);
}

;>;>;>;i++){

Endret av Øyvind Espnes
Lenke til kommentar

For at koden skal vite om dørvrideren er åpen eller lukket må du ha to endebrytere av noe slag. En for åpen lås og en for lukket lås. Eventuelt kan du prøve en fiffig løsning med bare en endebryter som kan brukes som endebryter i den ene retningen og som referanse for den motsatte retningen.

 

Kan du forresten være så snill å ha koden din i en spoiler? Det er litt kjedelig å bla 600 linjer for å komme til bunns.

  • Liker 1
Lenke til kommentar

Hva med en variabel som veksler mellom 0 eller 1 hver gang du kjører motoren?

 

crappy psuedokode:

 

int x = 1; // sett x = 0 hvis du skal kjøre motsatt vei første gangen

 

i loopen:

 

if x = 0:

x = 1-x;

kjørMotorMedKlokka();

else if x = 1:

x = 1-x;

kjørMotorMotKlokka();

else

#error

Lenke til kommentar

Der er dumt å få den til å "huske" forrige retning den roterte. Hvis strømmen forsvinner under rotasjonen har du ingen måte å finne ut hvilken vinkel du har på motoren din. Med minst en endebryter har du i det minste en referanse å gå etter om du skulle miste posisjonen på motoren.

Lenke til kommentar

Siden det er en stepmotor så har du vel kontroll på om det faktisk skjer noe når den går i en retning, dersom det ikke skjer noe må du gå andre veien f.eks? Mulig det blir krøll siden motoren "stanger" i låsen?

 

Eller legg inn en "kartlegging" i initen der du lagrer posisjonen i xen nevnt over

Endret av r0zie
Lenke til kommentar

Der er dumt å få den til å "huske" forrige retning den roterte. Hvis strømmen forsvinner under rotasjonen har du ingen måte å finne ut hvilken vinkel du har på motoren din. Med minst en endebryter har du i det minste en referanse å gå etter om du skulle miste posisjonen på motoren.

Lenke til kommentar

Er det ikke bare å rotere motoren fullt begge veier hver gang arduinoen får strøm, for å kalibrere?

Men hvis du ikke har endebrytere så går motoren blokk i stokk.

Derfor mener jeg at man burde ha minst en bryter, slik at man kan bruke den som referanse ved kalibrering. Da kan man i det minste telle steg motsatt vei.

Lenke til kommentar

Mye synsing her nå ,men om motoren går "blokk i stokk" vil den vel plutselig trekke mye mer strøm, om du måler spenningen over en motstand foran motoren kan du vel ganske kjapt måle når det skjer?

 

Edit; Ikke nødvendigvis at det er feil med endestopp :)

Endret av r0zie
  • Liker 1
Lenke til kommentar

Jeg sliter fremdeles med koden.

Den nekter å kjøre motsatt etter at den har kjørt med klokken etter en avlesning. Hvorfor hopper ikke den over til ELSE IF etter første IF?

                     int x = 0;                       //startposisjon
                     int GY=sizeof(GREEN)+sizeof(YELLOW);
                     red=true;
                     for(i=0;i<GY;i++){
                     
                        if(item==GREEN[i] & x==0){ //her føyes til lesing av int.
                          red=false;
                          Serial.println("Opening");
                          myStepper.step(500);
                          x = 1;                   //skriver ny int.
                            delay(500);
                            digitalWrite(A2,HIGH);
                            tone(8, 428); 
                            delay(360);
                            noTone(8);
                             digitalWrite(A2,LOW);
                             break;
                        }else if(item==GREEN[i] & x==1){  //om int=1 så skal den altså gå motsatt
                          red=false;
                          Serial.println("Locking");
                          myStepper.step(-500);
                          x = 0;                      //skriver int til 0
                            digitalWrite(A0,HIGH);
                            tone(8, 444); 
                            delay(150);
                            noTone(8);
                            delay(60);
                            tone(8, 446); 
                            delay(150);
                            noTone(8);
                             digitalWrite(A0,LOW);
                             break;
                        }else{
                        
                        } 
Lenke til kommentar

Generelt så bør du bruke switchcase i steden for if setninger så blir livet lettere, men er ikke sikkert det har noe å si her..

 

tror du må bruke to stk & for å få "and"

 

Ser og ut som du setter x = 0 i starten av koden så da kommer du vel aldri inn i den andre if setningen siden du bruker break og faller ut av løkka..?

 

print ut x verdien så ser du om den faktisk endrer seg, og legg inn print når du går inn i tilfeller så ser du lettere hvor det stopper osv..

 

Tror koden kan skrives om litt.. Feks har du bare behov for en if setning så du kan flytte det andre under else siden du bare skal gjøre en av de om gangen.. ? Blir og lettere å holde styr på ting om du bruker funksjoner til å gjøre operasjoner som bare skal kjøre uten noen spesielle argument.. F.eks

 

  1. blablabla....
  2. Serial.println("Locking");
  3. myStepper.step(-500);
  4. x = 0; //skriver int til 0
  5. funksjon1();
  6. break;
  7. }

  1. void funksjon1(){
  2. digitalWrite(A0,HIGH);
  3. tone(8, 444);
  4. delay(150);
  5. noTone(8);
  6. delay(60);
  7. tone(8, 446);
  8. delay(150);
  9. noTone(8);
  10. digitalWrite(A0,LOW);
  11. }
Endret av r0zie
Lenke til kommentar
  • 3 uker senere...
  • 2 uker senere...

hei

 

Driver å programmerer en Multiwii om dagen, men jeg får ikke connectet pc'n og flightkontrollen.

 

Når jeg plugget den i før så fikk jeg opp COM Porter i manage device (Enhetsbehandler)

 

Men nå så finner jeg ikke COM porter mere der. men noe annet som kommer opp isteden (se bilder)

 

noen som har greie på dette?

post-123139-0-70099900-1419794815_thumb.png

post-123139-0-78247600-1419794884_thumb.png

Endret av minibil
Lenke til kommentar

hei

 

Driver å programmerer en Multiwii om dagen, men jeg får ikke connectet pc'n og flightkontrollen.

 

Når jeg plugget den i før så fikk jeg opp COM Porter i manage device (Enhetsbehandler)

 

Men nå så finner jeg ikke COM porter mere der. men noe annet som kommer opp isteden (se bilder)

 

noen som har greie på dette?

 

Kan du beskrive mer hva du prøver å gjøre?

Men ser ut på første skjermbilde at den bare får kontakt med programmereren, (Tingen mellom USB og MultiWII om du bruker en slik(usb to serial)).

 

Sikker på at koblingen er riktig og at multiwiien faktisk fungerer?

Lenke til kommentar

Noen som kan hjelpe meg med et problem jeg har?

 

Det jeg prøver å få til er at en step-motor skal følge frekvensen til en puls som mates inn på arduinoen, veldig likt "motor-knob" eksemplet.

Problemet er at det ikke blir sendt et kontinuerlig step signal selv om jeg øker frekvensen jevnt.

 

TRTACig.png

 

Gul: Step signal

Rød: Pulsen som lese av arduino

const int speedoDir = 8;
const int speedoStep = 5;
 
const int speedTeeth = 48; // Number of pulses per rotation
float tireDiameter = 0.5; // Diameter of tire (meter)
float tireCircumference = PI * tireDiameter;
 
const int UpdateInterval = 500; // milliseconds
float lastUpdate = millis();
unsigned long speedPulseCount = 0l;
float currentSpeed = 0;
int pos = 0;
int val = 0;
 
unsigned long curMillis;
unsigned long prevStepMillis = 0;
unsigned long millisBetweenSteps = 25; // milliseconds
 
void setup() {
  Serial.begin(9600);
  
  pinMode(speedoDir, OUTPUT);
  pinMode(speedoStep, OUTPUT);
  
  digitalWrite(speedoStep, HIGH);
  
  attachInterrupt(0, speedCount, RISING);
  
}
 
void loop() {
  
  if ( millis() - lastUpdate >= UpdateInterval ) {
    // Calculate
    noInterrupts();
    // Rotations per second
    currentSpeed = speedPulseCount / ( ( (millis() - lastUpdate) / 1000 ) * speedTeeth );
    // Speed in km/h
    currentSpeed = currentSpeed * tireCircumference * 3.6;
    interrupts();

    // Reset pulse counter
    speedPulseCount = 0;
    lastUpdate = millis();
  }
  
  // "Follow" routine
  currentSpeed = constrain( currentSpeed, 0, 220 );
  val = map( currentSpeed, 0, 220, 0, 400 );
  curMillis = millis();
  
  // Speed difference bigger than 2?
  if ( abs(val - pos) > 2 ) {
    // Positive direction?
    if ( (val - pos) > 0 ) {
      digitalWrite(speedoDir, LOW);
      speedStep();
      pos++;
    }
    
    // Negative direction?
    if ( (val - pos) < 0 ) {
      digitalWrite(speedoDir, HIGH);
      speedStep();
      pos--;
    }
  } 
}
 
void speedStep() {
  if (curMillis - prevStepMillis >= millisBetweenSteps) {
    prevStepMillis += millisBetweenSteps;
    digitalWrite(speedoStep, LOW);
    digitalWrite(speedoStep, HIGH);
  }
}
 
void speedCount() {
  speedPulseCount++;
}
Endret av BigJackW
Lenke til kommentar

 

Noen som kan hjelpe meg med et problem jeg har?

 

Det jeg prøver å få til er at en step-motor skal følge frekvensen til en puls som mates inn på arduinoen, veldig likt "motor-knob" eksemplet.

Problemet er at det ikke blir sendt et kontinuerlig step signal selv om jeg øker frekvensen jevnt.

 

 

Har ikke satt meg helt inn i koden din, men jeg husker at jeg brukte den innebygde koden til en steppermotor jeg hadde. Den var mye dårligere enn den koden jeg lagde selv. Dvs motoren gikk mye dårligere og hadde midre moment. Tror den innebygde koden var ment for andre steppermotorer.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...